From dx-aem
Check health of AEM project infrastructure — verifies component definitions, OSGi configs, dispatcher rules, and content structure against expected state. Use to diagnose configuration drift or after making infrastructure changes.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dx-aem:aem-doctorThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are a diagnostic tool for AEM project infrastructure. You check local files, AEM instance state, and project conventions, then print a status table with warnings.
You are a diagnostic tool for AEM project infrastructure. You check local files, AEM instance state, and project conventions, then print a status table with warnings.
This skill is read-only. Never modify, fix, or deploy anything.
Read .ai/config.yaml for:
aem.component-path — component definitions root (e.g., /apps/myproject/components/content/)aem.resource-type-pattern — expected resource type formataem.author-url — AEM instance URL (defaults to http://localhost:4502)aem.frontend-dir — frontend source directoryaem.brands — configured brands (if multi-brand)build.command — project build commandAlso read the component index if it exists — check .ai/project/component-index.md first, fall back to .ai/component-index.md.
Parse the argument:
components — check component definitions onlyosgi — check OSGi configurations onlydispatcher — check dispatcher rules onlycontent — check AEM content structure onlycode — check Java code for anti-patterns onlyall or no argument — check everythingFor each component in the component path:
Verify structure:
# Find all component .content.xml files
find <component-path-in-repo> -name ".content.xml" -path "*components*"
Check each component has:
.content.xml with valid jcr:primaryType and componentGroup_cq_dialog/.content.xml (dialog definition) — warn if missing.html (HTL template) — warn if missingsling:resourceSuperType reference is valid (if set)Cross-reference with component index:
If the component index exists (.ai/project/component-index.md or .ai/component-index.md), verify:
.content.xmlSearch for OSGi config directories:
find . -path "*/osgiconfig/*" -name "*.cfg.json" -o -name "*.config" | head -30
Check:
.cfg.json)Search for dispatcher config:
find . -path "*/dispatcher/*" -type f | head -20
If dispatcher config exists, check:
If AEM MCP is available, verify:
Sites exist:
mcp__plugin_dx-aem_AEM__fetchSites
Compare against configured content paths in .ai/config.yaml.
Templates exist:
mcp__plugin_dx-aem_AEM__getTemplates
Verify templates referenced by components are available.
Components registered: For a sample of components from the index, verify they exist on AEM:
mcp__plugin_dx-aem_AEM__getComponents
path: "<component-path>/<sample-component>"
If aem.frontend-dir is configured:
Check that all components with dialog definitions have frontend files:
_cq_dialog, check if a matching JS/SCSS file exists in the frontend dirCheck brand coverage (if multi-brand):
aem.brands, verify brand-specific overrides directory existsScan Java source files for patterns that cause issues in AEM as a Cloud Service. Each check is a targeted grep — report matches with file and line number.
Detect via grep patterns in project Java source (**/core/**/src/main/**/*.java):
| Anti-Pattern | Grep Pattern | Severity |
|---|---|---|
| Scheduler API (runs on all cluster instances) | implements Runnable in files with Scheduler.PROPERTY_SCHEDULER | ⚠ warn |
| Static ResourceResolver (stale sessions) | private static ResourceResolver | ✗ error |
| Administrative resolver (removed in Cloud Service) | getAdministrativeResourceResolver | ✗ error |
| ResourceResolver not in try-with-resources | getServiceResourceResolver in files WITHOUT try (ResourceResolver | ⚠ warn |
| Path-bound servlet (bypasses ACLs) | sling.servlet.paths | ⚠ warn |
| Mutable state in OSGi service | @Component class with non-final private.*Map|List|Set|int|long|boolean fields that aren't @Reference/@Inject/@OSGiService/@ValueMapValue | ⚠ warn |
| Deprecated SCR annotations | import org.apache.felix.scr.annotations | ⚠ warn |
| Hardcoded AEM paths | String literals matching /content/dam/, /content/ followed by a specific site name, or /apps/ | ⚠ warn |
| JCR Session direct access | .adaptTo(Session.class) outside test files | ⚠ warn |
| Absolute resource type in HTL | resourceType='/apps/ in *.html files | ⚠ warn |
How to scan: Run greps in parallel. For each hit, report the file path and line. Skip test files (**/test/**) for all checks except the HTL check. Keep output concise — list up to 5 matches per pattern, then +N more.
Use this exact format with status indicators:
✓ — check passed⚠ — warning (works but attention needed)✗ — error (broken or missing)=== AEM Project Doctor ===
Component Definitions Status
─────────────────────────────────────────────────────────
<component-name> ✓ complete
.content.xml ✓ valid
_cq_dialog/.content.xml ✓ present
HTL template ✓ found
<component-name> ⚠ incomplete
_cq_dialog/.content.xml ✗ MISSING
...
OSGi Configurations Status
─────────────────────────────────────────────────────────
<pid>.cfg.json ✓ valid JSON
Runmodes: dev, qa, stage, prod ✓ all present
...
Dispatcher Status
─────────────────────────────────────────────────────────
Rewrite rules ✓ valid
Cache rules ✓ consistent
...
AEM Instance (<author-url>) Status
─────────────────────────────────────────────────────────
Sites configured ✓ N sites found
Templates available ✓ N templates
Components registered ✓ N/M registered
...
Frontend Status
─────────────────────────────────────────────────────────
Component coverage ✓ N/M have FE files
Brand overrides ✓ N brands, no orphans
...
Code Anti-Patterns Status
─────────────────────────────────────────────────────────
Scheduler API (use Sling Jobs) ✓ none found
Static ResourceResolver ✗ 2 hits
MyService.java:15, AnotherService.java:42
Administrative resolver ✓ none found
...
Summary: X passed, Y warnings, Z errors
For each warning or error, add a one-line explanation below the status line:
_cq_dialog/.content.xml ✗ MISSING
Component has no authoring dialog — intentional?
End with a summary line:
All checks passed.N warnings — review items marked ⚠N errors — items marked ✗ need attention⚠ AEM not reachable at <author-url>. Skipping instance checks.⚠ No dispatcher configuration found. Skipping.⚠ No OSGi configurations found. Skipping./aem-doctor — Runs all health checks: verifies 45 component definitions match source XML, validates OSGi configs exist, checks dispatcher rules for proper cache headers, confirms content structure paths are accessible, and scans Java code for anti-patterns. Reports 2 warnings (missing dispatcher rule, stale OSGi config) and 0 errors.
/aem-doctor code — Runs only the code anti-pattern scan. Greps Java source for deprecated APIs, static ResourceResolvers, path-bound servlets, and other Cloud Service anti-patterns. Reports 1 warning (deprecated SCR annotation in LegacyService.java) and 0 errors.
/aem-doctor (AEM not running) — Checks local file structure (component definitions, OSGi configs, dispatcher rules) and code anti-patterns successfully. Skips AEM instance checks with warning: "AEM not reachable at http://localhost:4502. Skipping instance checks." Reports local-only results.
/aem-doctor (after failed deployment) — Detects 3 errors: component dialog XML has invalid field type, OSGi config references non-existent PID, and content path returns 404. Each error includes the file path and suggested fix action.
"AEM not reachable — skipping instance checks"
Cause: AEM author is not running or the URL in config is wrong.
Fix: Start AEM or update aem.author-url in .ai/config.yaml. Local file checks still run — only live instance checks are skipped.
False positives on dispatcher rules Cause: The project uses a non-standard dispatcher configuration layout. Fix: Review the reported paths. If the dispatcher config is in an unusual location, the check may not find it. This is a warning, not an error.
Component definition mismatch warnings
Cause: Source XML was edited but not deployed, or the AEM instance has a different version of the component.
Fix: Deploy the latest code with mvn clean install -PautoInstallPackage and re-run /aem-doctor to verify the definitions match.
.ai/config.yamlnpx claudepluginhub easingthemes/dx-aem-flow --plugin dx-aemScans existing projects for health gaps across infrastructure, security, code quality, and harness setup. Provides a severity-ordered report of issues to fix.
Audits a codebase across 29 dimensions — security, privacy, compliance (HIPAA/PCI/SOC 2), architecture, testing, performance, DevOps, UX, SEO, AI/ML, and more. Generates structured docs and files remediation tickets.
Audits project configuration and documentation for drift, staleness, and broken references. Scans CLAUDE.md files, configs, plugin manifests, and knowledge files.