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.
npx claudepluginhub easingthemes/dx-aem-flow --plugin dx-aemThis skill is limited to using the following tools:
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.
Orchestrates content-first development workflow for AEM Edge Delivery Services. Ensures test content exists before implementing JS/CSS/block changes, bug fixes, or core functionality.
Generates developer guide for AEM Edge Delivery Services projects by analyzing codebase structure, custom implementations, and design tokens. Use for onboarding or technical handovers.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
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.yaml