Repository navigation
fix(lint): never throw on odd frontmatter or huge entities, and place and find diagnostics correctly - #43
Conversation
… and find diagnostics correctly - Take the frontmatter's closing line the way Comark does, so YAML on the `---` line no longer shifts token lines past the source. - Run each rule on its own; a rule that crashes reports one diagnostic and the others still run. - Read character references past U+10FFFF as U+FFFD instead of throwing. - Skip HTML blocks and code in comark/unclosed-block and comark/malformed-attributes. - Report `:name[…]` shorthand blocks and components inside them as unknown components. - Place unsafe URLs and broken anchors where they start an attribute or link, not on the same text in prose. - Read attribute values with nested braces and escaped quotes, so a key set twice after one is still found.
Latest result Pull request merged. Final answersSession Pull request merged. Session Waiting for GitHub merge request 244d772d-0d09-4ab6-af06-f57770db79b5. Session Updated the branch with main because main changed packages/lint/test/lint.test.ts after its checks ran; waiting for checks on the new head. Session Updated the branch with main because main changed packages/lint/test/lint.test.ts after its checks ran; waiting for checks on the new head. Session Updated the branch with main because main changed packages/lint/test/lint.test.ts after its checks ran; waiting for checks on the new head. Session Updated the branch with main because main changed packages/lint/test/lint.test.ts after its checks ran; waiting for checks on the new head. Session Updated the branch with main because main changed packages/lint/test/lint.test.ts after its checks ran; waiting for checks on the new head. Session Updated the branch with main because main changed packages/lint/test/lint.test.ts after its checks ran; waiting for checks on the new head. Session Updated the branch with main because main changed packages/lint/test/lint.test.ts after its checks ran; waiting for checks on the new head. Session Updated the branch with main because main changed packages/lint/test/lint.test.ts after its checks ran; waiting for checks on the new head. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Rule isolation — Crashing lint rules now produce a diagnostic while allowing the remaining rules to run.
- Source and token mapping — Frontmatter offsets, raw HTML/code ranges, shorthand components, and nested attribute scanning now follow Comark's parser behavior.
- Diagnostic placement and URL decoding — Anchor and unsafe URL matches are constrained to attribute values, and oversized numeric entities decode safely.
- Regression coverage and documentation — The changed behaviors are covered through the public
lint()interface and described in the lint docs.
gpt-5.6-sol | 𝕏
comark-annotate
comark-carousel
comark-embed
comark-github-callouts
comark-include
comark-lint
comark-tabs
comark-zoom
commit: |

Follows #38. Fixes the review findings on
comark-lint. Each one has a regression test that goes throughlint().---title: x\n---\n::bad.source.tsnow applies Comark's frontmatter rule: the YAML starts at the fifth character, even on the first line, and an empty block isn't stripped. Token lines are offset by the closing---line, the line Comark's remaining content starts on, instead ofstate.parsedLines, which miscounts this case. The token-to-source lookups are guarded.lint()also runs each rule on its own, so a rule that crashes reports one diagnostic under its own rule id (naming the error and where to report it) and the other rules still run.�…;. A character reference past U+10FFFF, including one so long it parses asInfinity, decodes to U+FFFD as in a browser. Before,% 0x110000turnedInfinityintoNaN.comark/unclosed-blockfalse positives. Lines inhtml_block,code_block, andfencetokens are skipped bycomark/unclosed-blockandcomark/malformed-attributes. I couldn't trigger the indented-code case, because the opener pattern already needs three spaces or fewer. The skip covers it anyway, and it also covers fences nested deeper than the source scan sees.mdc_block_shorthandopeners count as block components, so:badge[x]at the start of a line, nested or not, gets reported. An inline token without a map takes its block's map, so:chipinside:pill[see :chip[y]]is found too. This also numbers shorthand blocks forcomark/plugin-issueplacement.",',=,(, or<. The same text in prose is skipped. I chose this over tracking element line ranges because Comark nodes carry no positions, and mapping elements back to tokens would take far more code. The check also gets two links on the same line right, which line ranges wouldn't.{…}scanner understands nesting and\escapes inside quotes. It both finds the closing}and splits the attributes, so[x]{foo={"x":"}"} foo=2}reportsfootwice. This matches how Comark parses it (it keepsfoo=2).The docs page says how a crashing rule reports itself, that HTML blocks are skipped, and how URLs are placed.
pnpm readypasses: 156 tests, Vite Doctor clean. The twounbound-methodwarnings ine2e/annotate.e2e.tsare already onmain.🤖 Generated with Claude Code