Desktop SonarQube Rules — Yosemite Crew
SkillDev toolsHelps your agent fix SonarCloud code issues and write Sonar-clean Electron app code.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Desktop SonarQube Rules — Yosemite Crew skill
About this capability
Use when fixing SonarCloud issues in apps/desktop or writing Sonar-clean Electron and renderer code. Covers the enforced rule categories, the accepted role=dialog deferral, CSP and page-asset rules, and links the live SonarCloud project.
What this skill tells your AI
The instructions your AI receives, as published by yosemitecrew/yosemite-crew in .agents/skills/desktop-sonar/SKILL.md and read by ahel’s review.
Description
Use this skill when fixing SonarCloud issues in apps/desktop, or when writing new desktop code
that must pass Sonar checks. Covers the rule categories enforced on the desktop project, the
accepted deferral, and the fix patterns — plus where the authoritative issue list lives.
TRIGGER: any mention of "sonar", "code quality", or "lint issues" while working in apps/desktop,
or when writing new Electron/renderer code.
Surface note: this is the Codex/AGENTS copy. Mandatory checks live in
apps/desktop/AGENTS.md; the skill index is in the repo rootAGENTS.md. The Claude Code copy is.claude/skills/desktop-sonar/.
Authoritative Source — Do Not Freeze a Snapshot
The single source of truth for open issues is the SonarCloud project
yosemitecrew_Yosemite-Crew_Desktop. PR and branch pushes are analyzed in CI by the scan-only
_sonar stage of .github/workflows/ci.yaml; .github/workflows/sonar-cloud-analysis.yml is
the nightly type-aware backstop. The rule mix changes over time, so check the live
project for the current list rather than trusting any static dump. This skill documents the
categories and fix patterns that recur on this codebase, not a frozen issue count.
Do not reference the gitignored local-only Sonar tooling in any tracked file — that workflow lives
in the gitignored CLAUDE.local.md.
Mandatory Checks — run from apps/desktop/ after every change
pnpm run type-check # tsc (app) + tsc (tests)
pnpm run lint # eslint .
pnpm run archlint # local proxy for complexity / cyclic deps / dead code
pnpm test # full Jest suite (fast here)
There is no eslint-plugin-sonarjs wired into desktop. The local proxy for cognitive /
cyclomatic complexity and dead code is archlint (.archlint.yaml). The authoritative
complexity and smell check is still the SonarCloud analysis.
Coverage gate
Desktop is gated by the same aggregate and PR added-line coverage floors defined in
.github/workflows/_test.yaml as the rest of the repo; see
docs/ci/coverage.md for the full explanation.
Durable caveat (fixed in #2238, kept here so it does not regress): coverageProvider: 'v8' needs
source maps to attribute coverage back to your .ts sources. apps/desktop/tsconfig.json sets
sourceMap: false, and only tsconfig.test.json overrides it to true. Dropping that override
would make v8-to-istanbul report every loaded line as executed, so newly added dead code would
measure as fully covered and neither the added-line nor the aggregate floor could catch it.
Canary check if you suspect the source-map wiring broke: append an exported function nothing calls, run coverage, and confirm its body reports zero hits. If it shows as covered, the source maps are off. See the "Running it locally" recipe in that doc.
Accepted Deferral
Web:S6819(prefer native<dialog>overrole="dialog") is deferred insrc/pages/tabbar.htmlwhere the overlay is shown/hidden via a CSS class or inline-display toggle rather thanshowModal(). Converting to a native<dialog>would change show/hide semantics, so these instances are intentionally left as-is. Do not "fix" them blindly — match the existing deferral unless you are also migrating the show/hide mechanism.
Security & Reliability (fix immediately — these are bugs/vulns, not smells)
Web:S7039— CSPunsafe-inline. Externalize inline<style>/<script>/style=""to.css/.jsfiles; keepstyle-src file:; script-src file:;. Register every new file inscripts/copy-static.jspageAssetsor it won't ship.Web:InputWithoutLabelCheck. Every input needs an associated<label>or anaria-label.
TypeScript / JS Rules (with one-line fixes)
| Rule | Fix |
|---|---|
typescript:S1874 | Deprecated webContents.goBack()/goForward() → webContents.navigationHistory.goBack()/goForward() (also canGoBack/canGoForward). |
*:S7764 | Prefer globalThis over bare window in renderer page scripts. |
*:S7761 | Prefer .dataset over get/set/removeAttribute('data-…'). |
*:S6582 | Optional chaining: a && a.b → a?.b. |
typescript:S6606 | Nullish coalescing: || → ??/??= when the left side can be 0/''. |
typescript:S7741 | === undefined over typeof x === 'undefined'. |
*:S7735 | Invert unexpected negated conditions (if(!x){A}else{B}) or use an early return. |
*:S3358 | Extract nested ternaries into a named helper. |
typescript:S3776 | Cognitive complexity > 15 → extract helper functions. |
typescript:S2004 | Functions nested > 4 levels → extract. |
typescript:S4325 | Remove unnecessary type assertions. |
typescript:S7748 | No zero-fraction numbers (1.0 → 1). |
typescript:S6564 | Remove redundant type alias. |
typescript:S6598 | Type literal with only a call signature → function type. |
typescript:S6551 | Robust error stringify: error instanceof Error ? error.message : String(error). |
typescript:S7754 | .some() over .find() when the result is used as a boolean. |
typescript:S2486 | Handle the caught error, or use a paramless catch {} for a deliberate ignore. |
typescript:S7780 | String.raw for strings containing backslashes. |
typescript:S7743 | Avoid a confusing IIFE with a parenthesized arrow body. |
typescript:S3735 | Remove a stray void operator. (void promise to satisfy no-floating-promises is fine and is not what this flags.) |
typescript:S4043 | Copy before sorting: [...arr].sort() / .toSorted(). |
Modern method preferences
| Rule | Fix |
| --------- | ------------------------------------------------------------------- | --- |
| *:S6557 | String.startsWith(...) over regex/indexOf at position 0. |
| *:S7781 | String.replaceAll(...) over global-regex replace. |
| *:S7765 | .includes() over indexOf(…) !== -1. |
| *:S7758 | codePointAt / String.fromCodePoint over the char-code variants. |
| *:S7767 | Math.trunc(x) over x | 0. |
Note:
javascript:S3504("declare withlet/const, notvar") has shown up in volume on recent scans of generated/page scripts — replacevarwithconst/let. Always confirm the current top rules against the live SonarCloud project before a cleanup sweep.
Gotchas
eslint --fixauto-fixes some of these but not CSP, accessibility, or complexity issues — fix those by hand.- After any fix, re-run
pnpm run type-check && pnpm run lint && pnpm run archlintbefore marking resolved; the final word is the SonarCloud analysis in CI. - Externalizing a page asset is only half the fix — it must also be added to
copy-static.js.
Signals
- GitHub stars
- 2k
- Forks
- 83
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
desktop-sonar- Source
- github.com/yosemitecrew/yosemite-crew