AgentStack
SKILL verified Apache-2.0 Self-run

Sonarqube Refactoring

skill-shikanime-labs-skills-sonarqube-refactoring · by shikanime-labs

A Claude skill from shikanime-labs/skills.

No reviews yet
0 installs
4 views
0.0% view→install

Install

$ agentstack add skill-shikanime-labs-skills-sonarqube-refactoring

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Sonarqube Refactoring? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

SonarQube Refactoring

Fix code quality issues flagged by SonarQube analysis, especially for PR quality gates.

Common Issue Patterns & Fixes

1. Cognitive Complexity (S3776 — limit 15)

When a function exceeds 15 cognitive complexity, extract helper methods:

Before: One large method with nested if, for, &&, || After: Extract 1-2 private methods per logical grouping

Extraction targets:

  • Field-by-field update building → applyXUpdates(tx, id, data)
  • Validation chains with early returns → validateX(data, context)
  • Nested loops with conditionals → buildXMap(data)

Target: Reduce to ≤15. Aim for 2-3 points below threshold to leave headroom.

2. Unnecessary Type Assertions (S1905, S4325)

SonarQube flags as X when the assertion doesn't change the type.

Pattern: getRequest() as { project?: ProjectContext } where the return type already includes the shape. Fix: Remove the as assertion entirely.

Pattern: return projects as Project[] where the function already declares Project[] return type. Fix: Change the function signature to match the actual data flow (accept/return Partial if that's what flows through), or remove the assertion if the types already align.

3. typeof undefined Comparison (S1535)

Before: typeof rest.locked !== 'undefined' After: rest.locked !== undefined

4. as any on delete Operations (S4325)

Before:

const effectiveData = { ...data }
delete (effectiveData as any).locked
if (project.locked && (effectiveData as any).locked !== false) { ... }

After:

const effectiveData: Record = { ...data }
delete effectiveData.locked
if (project.locked && effectiveData.locked !== false) { ... }

Using Record makes delete and property access type-safe without as any.

5. Duplicate Imports (S1128)

Before:

import type { Prisma } from "@prisma/client";
import type { Project, ProjectMembers, User } from "@prisma/client";

After:

import type { Prisma, Project, ProjectMembers, User } from "@prisma/client";

6. Replace if/else Chains with Zod (S3776 contributor)

When a function has 4+ if/else if branches doing type-based value conversion:

Before:

function secretValueToString(value: unknown): string {
  if (typeof value === "string") return value;
  if (
    typeof value === "number" ||
    typeof value === "bigint" ||
    typeof value === "boolean"
  )
    return String(value);
  if (value === null || value === undefined) return "";
  return JSON.stringify(value);
}

After:

const SecretValueSchema = z
  .union([
    z.string(),
    z.undefined().transform(() => ""),
    z.number().transform((v) => String(v)),
    z.bigint().transform((v) => String(v)),
    z.boolean().transform((v) => String(v)),
    z.null().transform(() => ""),
  ])
  .catch("");

// Usage:
groupObj[key] = SecretValueSchema.parse(value);

7. Replace Custom Concurrency Helpers with Promise.allSettled

Before: Custom runWithConcurrency(tasks, limit) with Set, Promise.race, manual tracking. After: Promise.allSettled(tasks.map(t => t())) — simpler, standard, sufficient for most cases.

Procedure

  1. Read the SonarQube annotation list — each issue has a rule ID and line

number

  1. Group by type — fix all instances of the same pattern together
  2. Fix simplest firsttypeof comparisons, duplicate imports, unnecessary

as

  1. Then structural — cognitive complexity via extraction, Zod replacement
  2. Run tsc --noEmit after each group to verify no new type errors
  3. Run testspnpm test -- --run to verify behavior

preserved

Pitfalls

  • Extracting methods changes this context — use arrow functions or

.bind(this) when passing extracted methods as callbacks

  • Record needs casts for Prisma — when passing values

from Record to Prisma calls, cast at the boundary: effectiveData.ownerId as string

  • Zod .catch('') handles the fallback — make sure the catch value matches

the expected empty state for your domain

  • After extracting methods, update call sites — the extracted method

parameters must match what's available in the calling context

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.