Add MDS044 horizontal-rule-style rule - #218
Conversation
Adds rule MDS044 that enforces a consistent thematic break style (dash/asterisk/underscore), exact length, and required blank lines to prevent setext heading collision. Addresses review comments from PR #205: - Fix() deduplicates adjacent blank line insertions (same pattern as blanklinearoundheadings) - ApplySettings uses settings.ToInt() for int/int64/float64 coercion - README uses proper YAML front matter and include directives - Prefix (blockquote/indent) is preserved when rewriting HR lines https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #218 +/- ##
==========================================
+ Coverage 94.33% 94.35% +0.02%
==========================================
Files 137 136 -1
Lines 15927 15755 -172
==========================================
- Hits 15025 14866 -159
+ Misses 551 543 -8
+ Partials 351 346 -5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Add tests for previously uncovered branches: Category(), DefaultSettings(), RequireBlankLines=false, Fix() no-op early return, splitHRLine with no delimiter, styleName underscore/dash, isBlankLine out-of-bounds, and ApplySettings error paths for non-string style, non-bool require-blank-lines, float64 length, and non-integer length. https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
There was a problem hiding this comment.
Pull request overview
Adds a new Markdown lint rule (MDS044) to enforce consistent thematic break (horizontal rule) formatting, including delimiter style, exact length, and surrounding blank lines, plus auto-fix and documentation.
Changes:
- Implement MDS044
horizontal-rule-stylerule with configurablestyle,length, andrequire-blank-lines, including auto-fix. - Add unit tests and rule fixtures (good/bad/fixed) plus rule documentation.
- Register the rule in the CLI and integration test harness; update rule index and plan status.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| plan/108_horizontal-rule-style.md | Marks plan tasks/acceptance criteria complete. |
| PLAN.md | Updates plan index to show item 108 as complete. |
| internal/rules/index.md | Adds MDS044 to the rule index. |
| internal/rules/horizontalrulestyle/rule.go | New rule implementation + settings parsing + auto-fix. |
| internal/rules/horizontalrulestyle/rule_test.go | New unit tests for Check/Fix/settings parsing. |
| internal/rules/MDS044-horizontal-rule-style/README.md | New rule documentation and examples. |
| internal/rules/MDS044-horizontal-rule-style/good/*.md | New “good” fixtures for multiple configurations. |
| internal/rules/MDS044-horizontal-rule-style/bad/*.md | New “bad” fixtures asserting expected diagnostics. |
| internal/rules/MDS044-horizontal-rule-style/fixed/*.md | New “fixed” fixtures asserting auto-fix output. |
| internal/integration/rules_test.go | Imports the new rule for integration fixture testing. |
| cmd/mdsmith/main.go | Imports the new rule so it’s available in the CLI. |
…tion - Remove trailing newline in rule_test.go (gofmt lint failure) - isBlankLine now treats lines containing only ">" markers and whitespace (e.g. "> " or ">") as blank, preventing false-positive diagnostics for thematic breaks inside blockquotes - Fix() / collectChanges now tracks the HR line's container prefix (e.g. "> ") and inserts it when adding blank lines, so the blank line stays inside the blockquote rather than exiting it - before/after maps changed from map[int]bool to map[int]string to carry the blank-line content - Add tests for blockquote blank-line detection and prefix-preserving Fix https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
Fires after every git push, looks up the open PR for the current branch, and requests jeduden as reviewer via gh api. https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
The previous hook used `if: "Bash(git push *)"` which only matched when the Bash command started with "git push". Compound commands like "git add && git commit && git push" were missed. The hook now reads stdin JSON and greps for "git push" anywhere in the command string. https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
Replace hard-coded jeduden/mdsmith repo path and jeduden reviewer with dynamically derived values. Use the /copilot-review-requests endpoint to request a Copilot code review instead of a specific human reviewer. https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
Documents that Fix() correctly inserts an empty blank line after a thematic break inside a list item. CommonMark does not require blank lines to be indented for subsequent content to remain in the list item. https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
…s format lint.NewFile builds File.Lines via bytes.Split(source, "\n"), so line slices do not include trailing newline bytes. Update the manual line slice construction in isBlankLine tests to match this representation. https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
…reviewer name gh repo view fails when the remote is not github.com. Derive the owner/repo by parsing git remote get-url origin instead. Also fix the reviewer name: the correct GitHub App login is copilot-pull-request-reviewer[bot], not the non-existent /copilot-review-requests endpoint. https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
…nch name $BRANCH was interpolated directly into the --jq string; branch names containing quotes or other special characters could break parsing. Pipe gh api output to a separate jq call and pass the branch via --arg so it is treated as data, not code. https://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa
|
🔍 Merge Queue — bisecting A larger batch failed CI. Bisection is isolating the culprit: this run tests up to 1 of 1 candidate PRs on Next: No action needed — you'll be notified when the culprit is isolated or this PR merges. |
|
✅ Merge Queue — merged This PR landed on Next: Done — nothing more to do here. |
Summary
Implements the MDS044 rule to enforce consistent horizontal rule (thematic break) formatting in Markdown documents. This rule validates delimiter style, exact length, and surrounding blank lines.
Key Changes
New rule implementation (
internal/rules/horizontalrulestyle/rule.go):-,*, or_)>container markers;>lines are treated as blankConfiguration support:
style: Choose delimiter style ("dash", "asterisk", or "underscore")length: Set exact number of delimiters required (default: 3)require-blank-lines: Toggle blank line enforcement (default: true)Comprehensive test coverage (
internal/rules/horizontalrulestyle/rule_test.go):Documentation (
internal/rules/MDS044-horizontal-rule-style/README.md):Test fixtures:
Integration:
Claude PostToolUse Hook (
.claude/settings.json)This PR also adds a
PostToolUsehook that automatically requests a Copilot code review after anygit push. The hook:git pushgh repo view(no hard-coded owner/repo)/copilot-review-requestsGitHub API endpointghCLI to be authenticated; silently no-ops (exits 0) ifghis unavailable or the push has no associated PRNotable Implementation Details
*ast.ThematicBreaknodessplitHRLine()function preserves leading context (blockquote markers, list indentation) when fixinghttps://claude.ai/code/session_01DMrBd9zRmy8SN9yuypUVMa