Repository navigation
chore(docs): make the LLM flattener indentation-aware before the #402 rollout - #418
Conversation
…lout
The flattener replaces JSX in place but emitted its fence body and closing
fence at column 0, keeping only the opening fence's indentation. For a
component nested in a list item that produces:
```bash <- 3 spaces, opens inside the <li>
pnpm add foo <- column 0, terminates the list item
``` <- column 0
The command becomes prose and the following step gets swallowed. 20 of the
#402 target sites are nested (18 in react-setups.md at 3 spaces,
bulma-ui-3-to-4.md at 2), so this had to land before any of them.
Both flattenPackageManagerTabs and flattenGenericTabs now capture the tag's
indentation and carry it onto every emitted line. The pattern is anchored to
the start of a line, so a component sitting mid-sentence no longer matches and
survives as visible JSX rather than an inline fence that corrupts the document.
Adds the shared translation module the component will use. The flattener now
imports renderCommand from it instead of its own toPnpm, so the "no second
source of truth" property in its header comment is mechanically true — and a
test asserts the flattened body equals the pnpm tab for every table row. A
`command` may now hold several `;`-separated lines, which is what the Quick
Start scaffold sequences need.
Adds a build gate: main() throws if a rewritten artifact still contains tab JSX
outside code, has an unterminated fence, or has a fenced block dedented below
its opening fence. That last check is the one that catches the bug above —
CommonMark pairs those fences happily, so parity alone sees nothing wrong.
Coverage goes 21 -> 64, including a corpus test that runs every shipped page
through transform() and asserts the invariants, so a future nested usage fails
here instead of silently in llms-full.txt.
Verified: the LLM artifacts are byte-identical to a pre-change baseline build,
so this closes the latent defect without moving any published output.
WalkthroughThe change adds shared package-manager command translation, updates tab flattening to preserve indentation and Markdown structure, strengthens fenced-code and residual-JSX verification, and adds unit, gate, and full-documentation-corpus tests. ChangesDocumentation flattening and verification
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Preview DeploymentPreview URL: https://2ba556ab.bestax.pages.dev |
There was a problem hiding this comment.
Pull request overview
This PR hardens the docs LLM-artifact flattener ahead of the #402 tabs rollout by making the JSX-to-Markdown rewrite indentation-aware (so list nesting isn’t corrupted), centralizing package-manager command translation in a shared module, and adding a verification gate + broader test coverage to catch silent artifact corruption.
Changes:
- Update
flatten-llms-tabs.mjsto preserve indentation on all emitted lines and addverifyArtifact()checks for residual tab JSX and fence-structure corruption. - Add shared
translate.mjsfor pnpm→npm/yarn/bun command rendering, and tests to keep the flattener’s emitted pnpm output in sync with the shared translator. - Add targeted indentation tests plus a corpus-wide test to prevent future docs shapes from silently breaking
llms*.txt/ per-page.mdtwins.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/src/components/PackageManagerTabs/translate.mjs | Introduces a shared translation/rendering module for package-manager commands. |
| docs/scripts/package-manager-translate.test.mjs | Unit tests for translation + assertion that the flattener emits the exact pnpm rendering from the shared module. |
| docs/scripts/flatten-llms-tabs.mjs | Makes flattener indentation-aware, imports renderCommand, and adds artifact verification + build-fail gate. |
| docs/scripts/flatten-llms-tabs.indent.test.mjs | Tests indentation propagation, multi-segment commands, idempotency, and verifier failure modes. |
| docs/scripts/flatten-llms-corpus.test.mjs | Runs the flattener across the docs corpus and asserts key invariants (no residual JSX, no empty fences, idempotency). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Deep review — 0 blocking · 2 advisory
| # | Severity | Area | Finding | Location |
|---|---|---|---|---|
| 1 | 🔵 Advisory | Robustness | Dedent gate is blind to fences opened at ≥4 spaces (two-digit ordered lists, nested lists) — maskFences only recognizes opens at 0–3 leading spaces, so open.indent is always ≤3 and the dedent check can never fire for deeper nesting. The flattener itself is correct at those depths; this is a hole in the safety net, not the fix. |
docs/scripts/flatten-llms-tabs.mjs:150,178 |
| 2 | 🔵 Advisory | Robustness | Dedent predicate flags any non-blank body line less-indented than the opening fence, so legitimately flush-left content inside an indented fenced block (a heredoc, ASCII art) would false-positive and fail the build/corpus test. Corpus is clean today, so no current impact. | docs/scripts/flatten-llms-tabs.mjs:179 |
Overall: The change is sound and does exactly what it claims. I ran pnpm test (64/64 green), confirmed there are currently zero <PackageManagerTabs> usages in the corpus so the toPnpm -> renderCommand(cmd,'pnpm') swap is a genuine no-op for published output, and verified the generic-<Tabs> reindentBlock change is identity for every existing skills/API page (their TabItem bodies share a 0-space margin, so shared===0 && indent==='' short-circuits). The riskiest part is the new verifyArtifact build gate — not because it's wrong, but because it's a heuristic whose coverage is narrower than the flattener it guards; the human should focus there and decide whether the two gaps below are worth closing before the #402 rollout leans on it.
Residual risk: the addressed failure class is "flattener drops a tag's indentation -> silent list-item corruption in the concatenated artifacts." Ways it could still occur:
- Nesting deeper than 3 spaces — refuted for correctness (the flattener carries the captured indent at any depth; the 6-space unit test passes), but the gate would miss a future regression there (finding #1). A downstream stray fence sometimes trips the unterminated-fence check instead, but that's incidental, not guaranteed in a concatenated doc.
- Generic
<Tabs>####breaking out of a list — the fix carriesindentonto the heading, butverifyArtifacthas no heading-level dedent check, so only a fence inside the TabItem body would be caught, not the heading itself. Covered by unit + corpus tests, not by the gate. - Mid-line / unquoted / braced-template tags — refuted: the line-anchored regex leaves them as raw JSX and
verifyArtifact's residual-JSX scan turns that into a loud build failure (tested).
🏄 Clean set, brah — the flattener now hugs its indentation all the way down the line instead of dumping the body out at column zero and wiping the next page. Artifacts stay byte-for-byte with the baseline, tests doubled, and the new build gate is a solid paddle-out even if it can't see past the 3-space break. No blockers in the water — ship it and catch the #402 rollout on the next set. 🤙
Two review findings, both valid. main() verified only when transform() had changed the file. That exempted exactly the shape the gate exists to catch: a mid-line tag, which the line-anchored pattern deliberately skips, leaves the artifact untouched and so never got verified. Confirmed against the previous commit — a mid-line <PackageManagerTabs> exits 0 there and exits 1 now. Verification now runs for every artifact matching NEEDS_FLATTENING; only the write is conditional. The unit tests could not have caught this: verifyArtifact was already covered and correct, the wiring around it was wrong. Added flatten-llms-gate.test.mjs, which runs the real script over a temp build dir and asserts the process exit code, including that the prefilter still spares unrelated malformed pages. translate.mjs claimed passthrough segments were emitted "byte-identically", but splitSegments trims and collapses whitespace. The guarantee is that a passthrough line is the same on every tab, not that it matches the source byte for byte; reworded, and pinned with a test. 70 tests, up from 64. LLM artifacts still byte-identical to the baseline build.
|
Both addressed in 84dcbea.
|
Preview DeploymentPreview URL: https://2d6112a0.bestax.pages.dev |
|
deep-review: The prior review predates 84dcbea and never saw the gate fix. Be adversarial about the gate itself, not the flattener.
|
There was a problem hiding this comment.
Deep review — 0 blocking · 2 advisory
| # | Severity | Area | Finding | Location |
|---|---|---|---|---|
| 1 | 🔵 Advisory | Robustness | Gate is structurally blind to fences indented ≥4 spaces (open.indent can only ever be 1–3), so a deep-nested emission that regressed to a column-0 body can evade the dedent signal; scoped away from #402's sites (all ≤3 sp) |
docs/scripts/flatten-llms-tabs.mjs:150 |
| 2 | 🔵 Advisory | Robustness | Dedent predicate false-positives on valid CommonMark — a fence opened at 1–3 spaces with column-0 content (a legal code block) is flagged, which could redden a future build | docs/scripts/flatten-llms-tabs.mjs:178 |
Overall: The change is sound and does what it claims. I chased the wiring bug the gate-fix commit (84dcbea) targets and confirmed it is genuinely closed: main() now runs verifyArtifact before the after === before short-circuit, and flatten-llms-gate.test.mjs is not vacuous — it shells out to the real script over a seeded temp dir, asserts result.ok === false on the no-op mid-line-tag shape, and matches the specific unflattened tab JSX / failed verification stderr strings, so a wiring regression (or a crash for any other reason) fails the assertion rather than passing silently. The byte-identical-to-baseline claim also holds for current content: there is no <PackageManagerTabs> in the tree yet, every real theme <Tabs>/<TabItem> is at column 0 (so reindentBlock is the identity), and the indented <Tabs> are bestax's own component inside tsx fences (masked). The riskiest part is the gate's own heuristics, not the flattener — both advisories are edges of the verifier's coverage, both currently harmless, both worth the human deciding on before more pages convert in later #402 PRs.
Residual risk:
- Deep nesting (≥4 spaces).
maskFencesonly recognizes an opening fence at 0–3 leading spaces (CommonMark's own indented-code-block rule), soopen.indentis never ≥4 and the dedent check cannot see a fence opened deeper than 3 spaces. Refuted for this PR: #402's 20 nested sites are 18 at 3 spaces + 1 at 2 spaces, all ≤3, so both correct emission and corruption detection work there. Not refuted in general: a future component nested ≥4 spaces whose emission dropped indentation would produce a column-0 stray fence that usually trips the unterminated-fence check — except in the concatenatedllms-full.txt, where a later page's fence can pair with it and mask the region as code, evading both checks. The corpus test shares the blind spot (sameverifyArtifact). Recorded as advisory #1. - False-positive dedent. The predicate flags any less-indented non-blank body line under a 1–3-space opening fence, which is valid CommonMark. No current page or the full build triggers it (corpus + docs build green) and the flattener's own output is always uniformly indented, so it is latent — but an ordinary future edit with a slightly under-indented code block could redden the build. Recorded as advisory #2.
- llms.txt ↔ default-tab drift. Refuted: the flattener imports
renderCommandfrom the sharedtranslate.mjs, andthe flattener emits exactly the pnpm tabasserts the emitted body equalsrenderCommand(cmd,'pnpm')for every table row, including a multi-segment case. Passthrough segments are identical across tabs by construction (translateSegmentreturns the normalized segment unchanged for any non-verb first token), so the "passthrough differs across tabs" failure mode cannot occur.
🏄 Chill, clean set here, dudes — the flattener carries its indentation all the way to the beach now, the gate actually wipes out on a bad wave instead of paddling past it, and the baseline's byte-for-byte glassy. Couple of reef edges out past the 4-space break to keep an eye on, but nothing's gonna pitch you today. Send it. 🌊
The dedent check could only ever fire for a fence opened at 1-3 spaces: `maskFences` recognized an opening fence by CommonMark's top-level rule, so `open.indent` was never >= 4 and a corrupted emission nested deeper than one list level was invisible to it. It usually fell through to the unterminated-fence check — but not in `llms-full.txt`, where a later page's fence can pair with the stray column-0 one and mask the whole region as code, which is exactly the artifact the gate exists to protect. The 0-3 allowance is relative to the enclosing container, not the document, so seeing a nested fence means knowing the container's column. `maskFences` gains a `listAware` mode that tracks the innermost list item's content column; the closing fence is now measured against that column rather than against the opening fence's own indent, which is what lets a deep fence pair at all while still pairing a closer that sits below it — the corruption signature. `verifyArtifact` runs two passes, because its two questions want different readings. Residual tab JSX keeps the transform's view: widening it there would mask a region the flattener does rewrite and call a genuine miss clean. Only the dedent signal is taken from the `listAware` pass — an *unclosed* deep fence under that reading is usually a plain indented code block quoting a fence, and reddening a build over one would trade a blind spot for a false positive. Indentation is now measured in columns with tabs expanded to the next multiple of four, so a tab-indented fence still reads as the indented code block it is. Transform behaviour is unchanged by construction: with `listAware` off the container column is 0, which is the old rule exactly. Verified rather than assumed — `transform()` output is identical across all 144 shipped pages and their concatenation, both script versions leave a real build's artifacts untouched, and `verifyArtifact`'s verdict on every page is unchanged. 77 tests, up from 74. The deep-nesting case fails against the previous commit; the rest pin the edges the widening must not break.
|
Advisory #1 closed in #1 — the gate was blind past 3 spaces: closedConfirmed as stated. Fences balance, the whole region masks as code, and The fix follows the reason the hole existed: CommonMark's 0–3 allowance is relative to the enclosing container, not the document, so seeing a nested fence means knowing the container's column. Two deliberate limits, both because a gate that reddens valid builds is worse than one with a blind spot:
Incidental: indentation is now measured in columns with tabs expanded to the next multiple of four, so a tab-indented fence still reads as the indented code block it is. Without that, widening the pattern from #2 — dedent predicate false-positives on flush-left content: won't fixCorrect as described, and I'm leaving it. The two failure modes are the same bytes: "an author wrote a flush-left line inside an indented fence" and "a rewrite dropped the tag's indentation" are indistinguishable to any predicate, because the second is the first — that's what makes the corruption silent in the first place. So there is nothing to narrow on except the thing being detected. The asymmetry decides it. A false positive is a red build naming the file and the problem, fixed by indenting the block — which the source wanted anyway, since flush-left content inside an indented fence is fragile in CommonMark regardless of this script. A false negative is corrupted It also isn't the build that hits it first: the corpus test runs every shipped page through Noting honestly that #1's widening extends #2's surface — the predicate can now also fire on a deep fence — and that this is the trade I'm taking knowingly, not an oversight. Verification
Generated by Claude Code |
Preview DeploymentPreview URL: https://37492006.bestax.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
docs/src/components/PackageManagerTabs/translate.mjs (1)
56-61: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUnknown-manager guard is bypassed for passthrough segments.
translateSegment('cd app', 'cnpm')returns'cd app'instead of throwing, because theVERBScheck precedes theswitch. Validating the manager first makes the "programming error, not silent output" contract hold for every segment.♻️ Validate the manager before the passthrough return
export function translateSegment(segment, manager) { + if (!PACKAGE_MANAGERS.includes(manager)) { + throw new Error(`Unknown package manager: ${manager}`); + } const tokens = segment.split(' '); const [verb, ...rest] = tokens; if (!VERBS.has(verb)) return segment; if (manager === 'pnpm') return `pnpm ${segment}`;🤖 Prompt for 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. In `@docs/src/components/PackageManagerTabs/translate.mjs` around lines 56 - 61, Update translateSegment to validate the manager before the VERBS passthrough check, ensuring unknown managers throw for every segment while preserving existing translation behavior for supported managers.docs/scripts/flatten-llms-tabs.mjs (1)
70-76: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueA whitespace-only
commandemits an empty fence.
renderCommand('')yields'', sofencedemits an opening fence, one blank-ish line, and a closing fence — exactly the shapeflatten-llms-corpus.test.mjsline 54 reports as "emitted an empty bash fence". An authoring slip (command=" ") therefore fails the build with the corpus message rather than pointing at the tag. Consider leaving the tag untouched (or throwing with the tag text) when there are no segments.🤖 Prompt for 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. In `@docs/scripts/flatten-llms-tabs.mjs` around lines 70 - 76, Update flattenPackageManagerTabs to detect when the trimmed command passed to renderCommand is empty before calling fenced. Leave the original PackageManagerTabs tag unchanged (or raise an error containing the tag text) for whitespace-only commands, while preserving the existing replacement behavior for commands with content.docs/scripts/flatten-llms-corpus.test.mjs (1)
24-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThe
DOCS_DIRguard can't fire if the directory is missing.Collection happens at module scope, so a wrong/renamed
docs/docsmakesreaddirreject during import — the file fails to load with anENOENTinstead of the intended "corpus is non-empty" message. Moving the walk inside the guard test (or catching and lettingpagesstay empty) keeps the diagnostic.🤖 Prompt for 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. In `@docs/scripts/flatten-llms-corpus.test.mjs` around lines 24 - 37, Move the module-scope corpus collection using walk and DOCS_DIR into the test that validates pages.length, or catch directory-read failures so pages remains empty. Ensure a missing or invalid DOCS_DIR reaches the existing assertion and reports the intended non-empty corpus diagnostic instead of failing during module import.
🤖 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 `@docs/scripts/flatten-llms-tabs.mjs`:
- Around line 122-131: Update flattenGenericTabs to preserve non-TabItem JSX
found inside a Tabs block when TabItem entries are present, including it in the
generated output alongside the mapped items; alternatively, reject the transform
with a clear diagnostic. Ensure verifyArtifact or the relevant corpus invariant
can detect any content that is not preserved.
---
Nitpick comments:
In `@docs/scripts/flatten-llms-corpus.test.mjs`:
- Around line 24-37: Move the module-scope corpus collection using walk and
DOCS_DIR into the test that validates pages.length, or catch directory-read
failures so pages remains empty. Ensure a missing or invalid DOCS_DIR reaches
the existing assertion and reports the intended non-empty corpus diagnostic
instead of failing during module import.
In `@docs/scripts/flatten-llms-tabs.mjs`:
- Around line 70-76: Update flattenPackageManagerTabs to detect when the trimmed
command passed to renderCommand is empty before calling fenced. Leave the
original PackageManagerTabs tag unchanged (or raise an error containing the tag
text) for whitespace-only commands, while preserving the existing replacement
behavior for commands with content.
In `@docs/src/components/PackageManagerTabs/translate.mjs`:
- Around line 56-61: Update translateSegment to validate the manager before the
VERBS passthrough check, ensuring unknown managers throw for every segment while
preserving existing translation behavior for supported managers.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 1fdd3ace-1bc1-4ca8-9597-e70d4cab110a
📒 Files selected for processing (6)
docs/scripts/flatten-llms-corpus.test.mjsdocs/scripts/flatten-llms-gate.test.mjsdocs/scripts/flatten-llms-tabs.indent.test.mjsdocs/scripts/flatten-llms-tabs.mjsdocs/scripts/package-manager-translate.test.mjsdocs/src/components/PackageManagerTabs/translate.mjs
| return ( | ||
| lead + | ||
| items | ||
| .map(([, attrs, body]) => { | ||
| const label = attrLabel(attrs); | ||
| const text = reindent(body.trim()); | ||
| return label ? `${indent}${TAB_HEADING} ${label}\n\n${text}` : text; | ||
| }) | ||
| .join('\n\n') | ||
| ); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find <Tabs> blocks whose inner content includes non-TabItem lines.
fd -e md -e mdx . docs/docs | while read -r f; do
python3 - "$f" <<'PY'
import re, sys
src = open(sys.argv[1], encoding='utf8').read()
for m in re.finditer(r'<Tabs(?=[\s>])[^>]*>([\s\S]*?)</Tabs>', src):
inner = re.sub(r'<TabItem\b[^>]*>[\s\S]*?</TabItem>', '', m.group(1))
if inner.strip():
print(sys.argv[1], repr(inner.strip()[:120]))
PY
doneRepository: allxsmith/bestax
Length of output: 3276
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## candidate file"
fd -a 'flatten-llms-tabs\.mjs$' . | sed 's#^\./##'
echo "## outline"
ast-grep outline docs/scripts/flatten-llms-tabs.mjs || true
echo "## relevant ranges"
sed -n '1,220p' docs/scripts/flatten-llms-tabs.mjs | cat -n
echo "## parse behavior probe (same regex/branch logic as source)"
python3 - <<'PY'
import re, ast, pathlib
src = pathlib.Path('docs/scripts/flatten-llms-tabs.mjs').read_text()
print('contains TabItem-specific emit around lines 122-131:', 'TabItem' in src and 'label' in src and 'attrLabel' in src)
# Determine whether the file parses as valid JS; use babel/meriyah if available, otherwise source read is enough evidence for regex behavior.
tab_inner = '<Tabs command="x">\n<TabItem label="\n first" />\n\n admonition\n\n commentary\n\n<TabItem label="\n second" />\n</Tabs>'
# The script logic in that range only maps matched TabItems; we can re-map that behavior.
tab_items = re.findall(r'<\s*TabItem\b([^>]*)>([\s\S]*?)<\s*/\s*TabItem\s*>', tab_inner)
result = ''.join(f'{i}: {attrs!r} body={body!r}' for i, (attrs, body) in enumerate(tab_items))
non_tab = re.sub(r'<\s*TabItem\b[^>]*>([\s\S]*?)<\s*/\s*TabItem\s*>', '', tab_inner)
print('extracted TabItem bodies:', result)
print('non-TabItem inner remainder:', repr(non_tab))
print('non-TabItem remainder contains "admonition":', 'admonition' in non_tab)
print('non-TabItem remainder contains "commentary":', 'commentary' in non_tab)
PYRepository: allxsmith/bestax
Length of output: 12135
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## verifyArtifact"
sed -n '361,396p' docs/scripts/flatten-llms-tabs.mjs | cat -n
echo "## lint/test/format scripts"
sed -n '1,220p' package.json 2>/dev/null | cat -n || fd -a 'package\.json$' . | while read -r f; do echo "--- $f"; sed -n '1,220p' "$f" | cat -n; done
echo "## changed status"
git diff --stat HEAD || true
git diff -- docs/scripts/flatten-llms-tabs.mjs HEAD | sed -n '1,220p' || trueRepository: allxsmith/bestax
Length of output: 4072
Preserve and validate non-<TabItem> content inside <Tabs>.
flattenGenericTabs drops all non-<TabItem> JSX under <Tabs> when at least one TabItem is found, so stray content like embedded admonitions can disappear from the generated LLM artifact without failing verifyArtifact or a corpus invariant. Emit that content too, or fail the transform with a clear diagnostic.
🤖 Prompt for 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.
In `@docs/scripts/flatten-llms-tabs.mjs` around lines 122 - 131, Update
flattenGenericTabs to preserve non-TabItem JSX found inside a Tabs block when
TabItem entries are present, including it in the generated output alongside the
mapped items; alternatively, reject the transform with a clear diagnostic.
Ensure verifyArtifact or the relevant corpus invariant can detect any content
that is not preserved.
|
🎉 This PR is included in version 4.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 2.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 5.8.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 1.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
First PR of #402. No docs pages change here — this fixes a latent defect in the flattener that #408 shipped, which would have corrupted the LLM artifacts the moment a
<PackageManagerTabs>landed inside a numbered step.The bug
The flattener replaces JSX in place, but only the opening fence inherited the tag's indentation. Running the merged
transform()on a nested component:produced: