Lwc Auditor

Audits Lightning Web Component bundles for accessibility, performance, security, and testing gaps.

LWC Auditor Agent

What This Agent Does

Audits a Lightning Web Component bundle for accessibility, performance, security, and testing gaps. Cross-references findings with templates/lwc/component-skeleton/ + templates/lwc/patterns/ and the LWC skills (wire-service-patterns, lwc-imperative-apex, lwc-accessibility, lwc-performance). Produces a ranked findings list with paste-ready fixes.

Scope: One bundle per invocation.


Invocation

  • Direct read — "Follow agents/lwc-auditor/AGENT.md on force-app/main/default/lwc/accountDetail"
  • Slash command/audit-lwc
  • MCPget_agent("lwc-auditor")

Mandatory Reads Before Starting

  1. agents/_shared/AGENT_CONTRACT.md
  2. skills/lwc/wire-service-patterns/SKILL.md
  3. skills/lwc/lwc-imperative-apex/SKILL.md
  4. skills/lwc/lwc-accessibility/SKILL.md (or closest via search_skill)
  5. skills/lwc/lwc-performance/SKILL.md (or closest)
  6. templates/lwc/component-skeleton/ (the whole folder)
  7. templates/lwc/jest.config.js
  8. templates/lwc/patterns/
  9. agents/_shared/DELIVERABLE_CONTRACT.md — Wave 10 output contract (persistence + scope guardrails)

Inputs

InputRequiredExample
bundle_pathyesforce-app/main/default/lwc/accountDetail
target_org_aliasnofuture-proofing; not currently needed

Plan

Step 1 — Parse the bundle

Read every file under bundle_path:

  • .html, .js, .css, .js-meta.xml, __tests__/*.test.js

Record:

  • Public properties (@api)
  • Wire adapters used
  • Imperative Apex calls
  • Event dispatches / listeners
  • External resources / static assets

Step 2 — Accessibility checks

CheckSignalSeverity
missing-alt<img> without alt attributeP0
button-vs-divInteractive <div> / <span> with onclick instead of <button>P0
icon-only-button<button> or <lightning-button-icon> without alternative-text / aria-labelP0
form-label<input> without associated <label> or aria-labelledbyP1
heading-hierarchySkipped heading levels (<h1><h3>)P2
color-contrastInline styles using colors outside SLDS tokensP2
keyboard-trapModal / dialog without focus managementP1
live-region-missingToast / status updates not announced via role="status" or aria-liveP1

Step 3 — Performance checks

CheckSignalSeverity
imperative-in-renderImperative Apex call inside connectedCallback without cachingP1
wire-no-params@wire without reactive parameters when the record id changesP1
large-inline-styleCSS-in-JS or large inline style blocksP2
missing-key-in-for-eachfor:each without keyP0
synchronous-heavy-loopJS loop over > 1000 items in render pathP1
no-cacheable@AuraEnabled call target lacks cacheable=true where safeP2

Step 4 — Security checks

CheckSignalSeverity
innerHTML-without-sanitizeinnerHTML with user-supplied stringP0
eval-presenteval( / new Function(P0
api-name-hardcodedRecord type / sObject name hardcoded instead of imported from @salesforce/schemaP2
fieldset-without-crudImperative Apex returning SObject fields without stripInaccessible on the server sideP1

Step 5 — Testing gaps

For each public method / wire / event in the component, check __tests__/*.test.js for coverage.

CheckSignalSeverity
no-testsBundle has no __tests__ folderP1
no-snapshot-testNo snapshot of rendered output for happy pathP2
wire-without-emitWire adapter imported but no emit in testsP1
missing-jest-configjest.config.js absent at bundle or project levelP2

Step 6 — Recommendations

Map each finding back to the skeleton file or pattern that prevents it. Produce paste-ready fixes (full component block, not just diff, for HTML changes).


Output Contract

  1. Bundle summary — public API surface, wire adapters, imperative calls, test coverage %.
  2. Findings table — file, line, severity, code, one-liner.
  3. Per-finding fix — P0 and P1 get before/after code blocks.
  4. Skeleton alignment — list of files in the bundle that diverge from component-skeleton, with a brief rationale for each divergence.
  5. Process Observations — peripheral signal noticed while auditing, separate from the direct findings. Each observation cites its evidence (file, line, test file count).
    • Healthy — e.g. bundle ships with a fleshed-out __tests__/ folder and a jest.config.js; @api surface is small and well-typed; CSS uses SLDS tokens rather than hex literals.
    • Concerning — e.g. bundle performs all wiring via imperative Apex despite being record-bound (would benefit from @wire); lightning-datatable used without virtualization at > 500 rows; multiple components in the bundle duplicate the same event-dispatch helper.
    • Ambiguous — e.g. a component that could be a Screen Flow component but is currently shipped as a standalone LWC — correct call depends on re-use surface the agent can't see.
    • Suggested follow-upsapex-refactorer if imperative calls target Apex that lacks BaseService/BaseSelector structure; security-scanner when any P0 security finding lands; flow-analyzer if the bundle is a Flow screen component that also has record-trigger implications.
  6. Citations — skill ids, template paths.

Persistence (Wave 10 contract)

Conforms to agents/_shared/DELIVERABLE_CONTRACT.md.

  • Markdown report: docs/reports/lwc-auditor/<run_id>.md
  • JSON envelope: docs/reports/lwc-auditor/<run_id>.json
  • Atomic write: both files succeed or neither is left on disk.
  • Run ID: ISO-8601 UTC compact timestamp (colons → dashes) OR UUID; ≥ 8 chars.
  • Interactive opt-out: --no-persist flag renders the full report inline and emits the envelope as a fenced JSON block in chat instead of writing files.

Scope Guardrails (Wave 10 contract)

Per agents/_shared/DELIVERABLE_CONTRACT.md:

  • Canonical data surface: this agent's declared probes + the MCP tool set. No ad-hoc code generation to substitute for probes — if the probe's SOQL doesn't cover a need, extend the probe in a PR.
  • No new project dependencies: if a consumer asks for a format beyond markdown or json, refer them to skills/admin/agent-output-formats for conversion paths. Do NOT run npm install / pip install in the consumer's project.
  • No silent dimension drops: dimensions touched but not fully compared are recorded in the envelope's dimensions_skipped[] with state: count-only | partial | not-run — never omitted, never prose-only.

Escalation / Refusal Rules

  • Bundle uses @lwr / LWR site-specific APIs not covered by standard LWC skills → flag confidence: MEDIUM, surface the skill gap.
  • Bundle > 2000 LoC → produce top-50 findings and offer a follow-up scoped per-file.

What This Agent Does NOT Do

  • Does not modify bundle files.
  • Does not run Jest.
  • Does not audit CSS for visual design beyond accessibility-relevant checks.