Skip to content

chore(excalidraw-skill): encode text-overlap + GitHub-SVG lessons; ad…#21

Merged
emeraldleaf merged 2 commits into
mainfrom
chore/excalidraw-skill-text-overlap-fix
May 23, 2026
Merged

chore(excalidraw-skill): encode text-overlap + GitHub-SVG lessons; ad…#21
emeraldleaf merged 2 commits into
mainfrom
chore/excalidraw-skill-text-overlap-fix

Conversation

@emeraldleaf

@emeraldleaf emeraldleaf commented May 23, 2026

Copy link
Copy Markdown
Owner

The recent dev-loop diagram exposed two failure modes the skill didn't guide against. Both got fixed twice (PR #20) instead of being prevented up front. This commit encodes the lessons so future diagrams ship right the first time.

SKILL.md additions:

Text Width Validation (Prevent Overlap) — new subsection in Layout Principles.
Quantifies the issue: SVG doesn't wrap; 150-char line at 14px = ~1260px
wide and bleeds into adjacent columns if column width is ~840px. Includes a
per-character-width table and the four ways out (shorten, multi-element wrap,
single-column restructure, foreignObject). Cites the caught-in-the-wild
example from PR #20's Gaps section.

SVG Output for GitHub Embedding — new top-level section. Three rules for
hand-written SVG to render correctly on GitHub:
1. explicit width + height (without it, GitHub downscales to ~50% and text becomes illegible)
2. white background as first child (without it, transparent background = invisible text on GitHub dark theme)
3. single-column for any text >80 chars (SVG has no auto-wrap) Plus guidance on when the .excalidraw and .svg drift (document it inline).

Quality Checklist — bumped from 27 to 31 items, adding four explicit checks
for the GitHub-SVG scenario.

render_excalidraw.py changes:

Path A (Playwright render) now writes a sibling .svg alongside the .png.
New _make_github_friendly() helper post-processes Excalidraw's exportToSvg
output to add the width/height attributes and white background rect — so
Playwright-rendered SVGs land with the same GitHub-friendly shape that
hand-written ones now require. Docstring + main() print line updated.

.claude/scripts/rebuild-diagrams.sh (new):

Walks docs/*.excalidraw, regenerates .png + .svg outputs for any source
newer than its outputs. Skips up-to-date files unless --force. Single-file
mode for targeted rebuilds. CI-friendly exit code on failure.

What changed

How it was built

Verification

Touches (check only if applies)

  • EF Core migration (immutable once applied — see CLAUDE.md "Performance Rules")
  • CLAUDE.md or a See CLAUDE.md paraphrase (run /check-rules to audit drift)

Summary by CodeRabbit

  • New Features

    • Diagrams now produce GitHub-friendly SVGs alongside PNGs.
    • Added a bulk rebuild command to regenerate diagram outputs and report successes/failures.
  • Documentation

    • Expanded diagram guidelines with text-width validation and fixes to prevent overlap.
    • Added SVG-for-GitHub requirements (explicit sizing, white background, legibility) and guidance for keeping renders in sync.

Review Change Stack

…d rebuild script

The recent dev-loop diagram exposed two failure modes the skill didn't guide
against. Both got fixed twice (PR #20) instead of being prevented up front.
This commit encodes the lessons so future diagrams ship right the first time.

SKILL.md additions:

  Text Width Validation (Prevent Overlap) — new subsection in Layout Principles.
  Quantifies the issue: SVG <text> doesn't wrap; 150-char line at 14px = ~1260px
  wide and bleeds into adjacent columns if column width is ~840px. Includes a
  per-character-width table and the four ways out (shorten, multi-element wrap,
  single-column restructure, foreignObject). Cites the caught-in-the-wild
  example from PR #20's Gaps section.

  SVG Output for GitHub Embedding — new top-level section. Three rules for
  hand-written SVG to render correctly on GitHub:
    1. explicit width + height (without it, GitHub downscales to ~50% and text
       becomes illegible)
    2. white background <rect> as first child (without it, transparent
       background = invisible text on GitHub dark theme)
    3. single-column for any text >80 chars (SVG has no auto-wrap)
  Plus guidance on when the .excalidraw and .svg drift (document it inline).

  Quality Checklist — bumped from 27 to 31 items, adding four explicit checks
  for the GitHub-SVG scenario.

render_excalidraw.py changes:

  Path A (Playwright render) now writes a sibling .svg alongside the .png.
  New `_make_github_friendly()` helper post-processes Excalidraw's exportToSvg
  output to add the width/height attributes and white background rect — so
  Playwright-rendered SVGs land with the same GitHub-friendly shape that
  hand-written ones now require. Docstring + main() print line updated.

.claude/scripts/rebuild-diagrams.sh (new):

  Walks docs/*.excalidraw, regenerates .png + .svg outputs for any source
  newer than its outputs. Skips up-to-date files unless --force. Single-file
  mode for targeted rebuilds. CI-friendly exit code on failure.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@codecov

codecov Bot commented May 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0388422a-e353-4d59-bd2f-b6ef0953a0fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9ea66c0 and b91560d.

📒 Files selected for processing (3)
  • .claude/scripts/rebuild-diagrams.sh
  • .claude/skills/excalidraw-diagram/SKILL.md
  • .claude/skills/excalidraw-diagram/references/render_excalidraw.py

Walkthrough

This PR adds GitHub-friendly SVG output alongside PNGs for Excalidraw renders, a bulk incremental rebuild script for .excalidraw sources, and documentation describing text-fit validation and SVG requirements for GitHub embedding.

Changes

SVG Output Generation and Automation

Layer / File(s) Summary
SVG Generation and GitHub Post-Processing
.claude/skills/excalidraw-diagram/references/render_excalidraw.py
render_excalidraw.py generates both PNG and sibling .svg output. New _make_github_friendly() helper parses the rendered SVG, ensures explicit width/height (derived from viewBox when missing), and injects a white background <rect> as the first child. Module docstring and CLI output updated to document dual output.
Incremental Rebuild Automation
.claude/scripts/rebuild-diagrams.sh
New script batch-rebuilds .png/.svg outputs from .excalidraw sources. Discovers targets (explicit paths or all docs/**/*.excalidraw), detects stale sources via modification-time comparison, invokes render via uv run python, tracks rebuilt/skipped/failed counts, captures failure output tails, and exits non-zero on failure for CI integration.
Documentation and Validation Guidance
.claude/skills/excalidraw-diagram/SKILL.md
SKILL.md adds text width validation rules (estimate rendered width, remediate overflow), GitHub SVG output guidance (Playwright-based .svg generation preferred; hand-written fallback rules: explicit width/height, first-child white <rect>, single-column for long lines, font-size guidance), and expands the visual validation checklist with GitHub-specific checks.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title refers to the PR's core objectives—encoding lessons about text-overlap prevention and GitHub SVG compatibility—which aligns with the main changes (documentation expansion, render script enhancements, and rebuild tooling).
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/excalidraw-skill-text-overlap-fix

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 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 @.claude/scripts/rebuild-diagrams.sh:
- Around line 40-50: The find invocation in rebuild-diagrams.sh currently uses
-maxdepth 2 which limits discovery of .excalidraw files; update the TARGETS
population logic (the while/read block that uses find "$DOCS_DIR" -maxdepth 2
-name "*.excalidraw") to either remove the -maxdepth option so find searches
recursively, or make the depth configurable by introducing an environment
variable (e.g., MAX_DEPTH or EXCALIDRAW_MAXDEPTH) and substitute it into the
find command (falling back to no -maxdepth when unset); ensure you reference
DOCS_DIR and TARGETS so behavior remains the same and update the script header
comment to document the new behavior or variable.
- Around line 19-28: Add a fast-fail check that the external "uv" command is
available before attempting renders: after verifying RENDER_SCRIPT (and before
any per-file rendering loop), call a command-existence check (e.g., using
command -v or which) for "uv" and if it's not found emit a clear error like
"ERROR: required command 'uv' not found; please install or add to PATH" and exit
nonzero; update the script around the RENDER_SCRIPT validation to perform this
check so any missing dependency is reported immediately.
- Around line 66-71: The parameter expansion rel="${src#$REPO_ROOT/}" is
unquoted and triggers shellcheck SC2295; change the expansion to quote the
prefix so glob metacharacters in REPO_ROOT can't be interpreted — i.e., use
rel="${src#"$REPO_ROOT"/}" (adjusting the quoting around REPO_ROOT in the
${...#...} expression) to safely strip the repo root from src; update the line
that sets rel and run shellcheck to confirm the warning is resolved.
- Around line 78-84: The current command in the rebuild loop suppresses both
stdout and stderr (uv run python "$RENDER_SCRIPT" "$src" >/dev/null 2>&1),
hiding useful error output; change it to capture stderr to a temp file and only
suppress stdout so failures can print the error: create a temp file (mktemp)
before running the uv run python "$RENDER_SCRIPT" "$src" command, run it with
stdout redirected to /dev/null and stderr redirected into that temp file (e.g.,
>/dev/null 2>"$errfile"), on success remove the temp file and increment rebuilt,
on failure cat the temp file to echo the renderer error and increment failed,
and ensure you trap/cleanup the temp file (or fallback to simply only suppress
stdout by removing the 2>&1 redirection) — refer to RENDER_SCRIPT, the uv run
python invocation, and the rebuilt/failed counters to locate where to apply this
change.

In @.claude/skills/excalidraw-diagram/references/render_excalidraw.py:
- Around line 174-183: Validate the SVG string returned by page.evaluate before
post-processing and writing: check that svg_markup (from
page.evaluate("document.querySelector('`#root` svg').outerHTML")) is not None and
not an empty/whitespace-only string, and if it's invalid either log/raise an
error or skip writing the .svg file instead of passing it to
_make_github_friendly and svg_output_path.write_text; ensure any error includes
context (which page/selector) so callers can diagnose failures.

In @.claude/skills/excalidraw-diagram/SKILL.md:
- Line 436: Update the "Caught-in-the-wild example" paragraph (the line starting
"The cost of computing widths up front...") in SKILL.md to include a citation to
PR `#20` for the "Gaps" example; specifically append or insert a
parenthetical/reference like "(see PR `#20`)" or a markdown link to the PR after
the phrase that mentions the "Gaps" section so readers can find the full
context.
- Around line 494-503: Add blank lines before and after each fenced code block
so the triple-backtick fences are separated from surrounding text (fix MD031);
specifically, ensure there is an empty line before the "```xml" fence that opens
the <svg ...> example and an empty line after that closing "```", and likewise
add an empty line before and after the "```xml" fence that surrounds the <rect
width="1800" height="1500" fill="`#ffffff`"/> example so both fences are isolated
from neighboring paragraphs.
- Around line 629-642: Renumber the ordered lists under the "Visual Validation
(Render Required)" and "GitHub SVG (if the diagram is referenced from markdown)"
headings so the Visual Validation items are 1-7 (change current 22-27 to 2-7 and
make the first item 1) and the GitHub SVG items are 1-4 (change current 28-31 to
1-4); also insert a blank line immediately before the "GitHub SVG..." heading to
satisfy MD022 and ensure the file ends with a trailing newline to satisfy MD047.
Locate the two headings and the numbered list items in SKILL.md and update the
numeric prefixes accordingly, add the single blank line above the "GitHub SVG"
heading, and append a newline at EOF.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: 3c81794c-414b-4e27-b734-195f23dce46b

📥 Commits

Reviewing files that changed from the base of the PR and between 5484ac2 and 9ea66c0.

📒 Files selected for processing (3)
  • .claude/scripts/rebuild-diagrams.sh
  • .claude/skills/excalidraw-diagram/SKILL.md
  • .claude/skills/excalidraw-diagram/references/render_excalidraw.py

Comment thread .claude/scripts/rebuild-diagrams.sh
Comment thread .claude/scripts/rebuild-diagrams.sh Outdated
Comment thread .claude/scripts/rebuild-diagrams.sh Outdated
Comment thread .claude/scripts/rebuild-diagrams.sh Outdated
Comment thread .claude/skills/excalidraw-diagram/references/render_excalidraw.py Outdated
Comment thread .claude/skills/excalidraw-diagram/SKILL.md Outdated
Comment thread .claude/skills/excalidraw-diagram/SKILL.md
Comment thread .claude/skills/excalidraw-diagram/SKILL.md Outdated
All eight CodeRabbit findings on the initial commit were Quick-Win / Nit /
Minor severity — addressing each:

rebuild-diagrams.sh (4):
  1. Add `uv` PATH check up front (was discovered at first render attempt,
     hiding the real error in a redirect)
  2. Drop `-maxdepth 2` from the find — discovers diagrams at any depth
     under docs/ now (e.g., docs/a/b/c/diagram.excalidraw)
  3. Quote $REPO_ROOT in parameter expansion: `${src#"$REPO_ROOT"/}` —
     shellcheck SC2295, prevents accidental glob interpretation
  4. Capture render output to a temp file instead of `>/dev/null 2>&1` —
     on failure, print the last 20 lines of the actual error so the user
     doesn't need to re-run manually to see what went wrong

render_excalidraw.py (1):
  5. Guard `svg_markup` non-empty before writing the .svg sibling. Earlier
     query_selector already proved the element exists, so this is defensive
     — warn-and-continue on the unexpected empty-outerHTML case rather than
     silently writing a broken SVG.

SKILL.md (3):
  6. Add (PR #20) citation to the "Caught-in-the-wild example" so the
     reference is concrete and grep-able
  7. MD031 blank-lines-around-fences — added blank lines before/after the
     three ```xml fences in "SVG Output for GitHub Embedding"
  8. Restart ordered-list numbering at 1 in every Quality Checklist
     subsection (was continuous 1-31 across all subsections — confused some
     markdown parsers). Plus MD047 trailing newline on the file.

Not addressed: IDE's separate SonarLint warning about render() function
having cognitive complexity 19/15 — pre-existing on the function, not
flagged by CodeRabbit, and refactoring is scope creep.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@emeraldleaf
emeraldleaf merged commit 24decf8 into main May 23, 2026
6 checks passed
@emeraldleaf
emeraldleaf deleted the chore/excalidraw-skill-text-overlap-fix branch June 4, 2026 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant