Skip to content

ENG-1832 Add Obsidian eslint to the project - #1328

Open
trangdoan982 wants to merge 1 commit into
mainfrom
eng-1832-add-obsidian-eslint-to-the-project
Open

ENG-1832 Add Obsidian eslint to the project#1328
trangdoan982 wants to merge 1 commit into
mainfrom
eng-1832-add-obsidian-eslint-to-the-project

Conversation

@trangdoan982

@trangdoan982 trangdoan982 commented Aug 22, 2026

Copy link
Copy Markdown
Member

eslint-plugin-obsidianmd catches the plugin-guideline violations that get plugins rejected from the Obsidian community store, but wiring it in naively drowns the signal: its recommended set reports 168 new findings in apps/obsidian, of which only a handful can actually cost us the store listing. This adds a dedicated gate that reports only store blockers, and fixes the 15 real violations so the gate can be blocking from day one.

Replaces the closed #1188, which was blocked on ESLint 8. That's moot now — the repo is on ESLint 9.39.5 and typescript-eslint 8.67.0, so the plugin's peers are satisfied with no catalog scoping.

Review focus

  • packages/eslint-config/obsidian-store.js — the gate. Keeps only obsidianmd's own error-level rules and drops everything its recommended set drags in (eslint-comments, depend, import, security, sdl), which contributed 43 findings + 8 unused-directive errors unrelated to store review.
  • apps/obsidian/src/components/canvas/DiscourseToolPanel.tsxthe riskiest change. The drag ghost's 11 inline style writes became two class constants. Note the className on the JSX must stay a constant expression; the reactor writes it imperatively and React only clobbers props whose rendered value changed.
  • .github/workflows/ci.yaml — new job is blocking. Intentional, but it's a new way for PRs to go red.

Decisions worth challenging

  • The gate is not built on @repo/eslint-config. That config loads eslint-plugin-only-warn, which patches ESLint globally on import and forces every rule to "warn" — the exact distinction this gate exists to make. I verified an explicit "error" severity does not override it. Hence a separate config in a separate process. The alternative — dropping only-warn repo-wide — would turn 112 existing Obsidian warnings and 538 Roam warnings into hard errors, so it was rejected as out of scope.
  • It lives in packages/eslint-config, not apps/obsidian. It must register the preferArrows / react-hooks / turbo namespaces, or existing eslint-disable comments in our source raise Definition for rule ... was not found. That package already depends on all three; apps/obsidian does not.
  • scripts/ is exempt. All 22 no-console errors were in build and test-data tooling that never ships in the plugin bundle, so Obsidian never reviews it. Exempting it took the gate from 37 errors to 15, all in shipped code.
  • Only error-level rules are wired in. The 62 warn-level findings (prefer-window-timers, prefer-create-el, ui/sentence-case, …) are style advice, not store blockers. Deliberately deferred — 46 are auto-fixable and worth a follow-up ticket.
  • Tailwind over styles.css for the fixes, per project UI guidelines. No new CSS was needed.
  • pnpm lint is untouched. base.js and react-internal.js are unmodified, so Roam and the website are unaffected.

Verification

  • lint:store exits 0. Negative test: adding el.style.color = "red" is caught as an error with exit 1 — confirming severity survives, which is the whole point of the separate config.
  • check-types exits 0; build reports 0 errors.
  • Main apps/obsidian lint unchanged at 112 messages / 0 errors, before and after.
  • Roam lint 538 messages / 0 errors, no obsidianmd/* rules leaked.
  • prettier --check clean on all changed files.
  • Runtime, in the live Obsidian app over CDP: injected the new class set and the inline styles it replaced side by side and compared getComputedStyle. All 8 properties identical — display: flex, position: fixed, pointer-events: none, left: 0px, top: 0px, width: 50px, height: 50px, align-items: center — and .hidden resolves to display: none. (First run showed 3 mismatches purely from stale plugin CSS; reloading the plugin resolved all 3.)

Not covered: no unit tests — the change is lint config plus CSS-equivalent refactors, and the repo has no test setup for either. The drag-ghost interaction was verified by computed-style equivalence, not by performing an end-to-end drag on a canvas, so a manual drag is worth a reviewer's minute.

Known limits

  • The gate's rule list is derived from obsidianmd's recommended config at runtime, so a plugin upgrade that promotes a rule to error will start failing CI without a config change here. That's the intended behavior, but it makes eslint-plugin-obsidianmd upgrades worth reading closely.
  • eslint-plugin-obsidianmd wants @eslint/js@^9.30.1 while packages/eslint-config pins ^9.29.0. Install succeeds and nothing misbehaves, so I left the pin alone rather than widen scope.

🤖 Generated with Claude Code


Open in Devin Review

Add eslint-plugin-obsidianmd as a dedicated store-compliance gate that
reports only the rules which can get the plugin pulled from the Obsidian
community store, and fix the 15 violations it found.

The gate cannot be built on @repo/eslint-config: that config loads
eslint-plugin-only-warn, which patches ESLint globally on import and
forces every rule to "warn", erasing the error/warn distinction the gate
depends on. It therefore lives in its own config and runs in its own
process.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Aug 22, 2026

Copy link
Copy Markdown

ENG-1832

@vercel

vercel Bot commented Aug 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
discourse-graph Ready Ready Preview Aug 22, 2026 6:41pm

Request Review

@supabase

supabase Bot commented Aug 22, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project zytfjzqyijgagqxrzbmz because there are no changes detected in packages/database/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@graphite-app

graphite-app Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

PR size/scope check

This PR is over our review-size guideline.

  • Recommended: ~200 lines changed
  • Acceptable limit: up to 400 lines when well-scoped/self-contained
  • Preferred file count: fewer than 5 files

Please split this into smaller PRs unless there is a clear reason the changes need to land together.

If keeping it as one PR, please add a brief justification covering:

  • What single problem this PR solves
  • Why the files/changes are coupled

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

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