Skip to content

Commit ae188ee

Browse files
authored
Merge pull request #115 from easingthemes/claude/review-aem-skills-GspOe
2 parents 4aba828 + 473fee5 commit ae188ee

2 files changed

Lines changed: 37 additions & 5 deletions

File tree

docs/reference/skill-catalog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ dx-req-dod ── (standalone, needs wiki-dod-url in config + linked PR in ADO,
197197
| aem-component | `/aem-component` | `<component-name>` | Find all source files, AEM pages, and dialog fields for a component (multi-platform, data-driven) | Component report |
198198
| aem-page-search | `/aem-page-search` | `<component-name>` | Find all AEM pages using a specific component | Page list |
199199
| aem-refresh | `/aem-refresh` | none | Update `.ai/project/` seed data from plugin, external docs repo, or manual sources | Seed data files |
200-
| aem-doctor | `/aem-doctor` | `[components\|osgi\|dispatcher\|all]` | Check AEM project infrastructure health | Status report |
200+
| aem-doctor | `/aem-doctor` | `[components\|osgi\|dispatcher\|content\|code\|all]` | Check AEM project infrastructure health — includes code anti-pattern scan | Status report |
201201

202202
---
203203

plugins/dx-aem/skills/aem-doctor/SKILL.md

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: aem-doctor
33
description: 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.
4-
argument-hint: "[components|osgi|dispatcher|content|all]"
4+
argument-hint: "[components|osgi|dispatcher|content|code|all]"
55
allowed-tools: ["read", "edit", "search", "write", "agent", "AEM/*", "chrome-devtools-mcp/*"]
66
---
77

@@ -28,6 +28,7 @@ Parse the argument:
2828
- `osgi` — check OSGi configurations only
2929
- `dispatcher` — check dispatcher rules only
3030
- `content` — check AEM content structure only
31+
- `code` — check Java code for anti-patterns only
3132
- `all` or no argument — check everything
3233

3334
## 3. Run Checks
@@ -115,6 +116,27 @@ If `aem.frontend-dir` is configured:
115116
- For each brand in `aem.brands`, verify brand-specific overrides directory exists
116117
- Check for orphaned brand files (brand override without a base component)
117118

119+
### 3f. Code Anti-Pattern Scan
120+
121+
Scan 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.
122+
123+
**Detect via grep patterns** in project Java source (`**/core/**/src/main/**/*.java`):
124+
125+
| Anti-Pattern | Grep Pattern | Severity |
126+
|---|---|---|
127+
| Scheduler API (runs on all cluster instances) | `implements Runnable` in files with `Scheduler.PROPERTY_SCHEDULER` | ⚠ warn |
128+
| Static ResourceResolver (stale sessions) | `private static ResourceResolver` | ✗ error |
129+
| Administrative resolver (removed in Cloud Service) | `getAdministrativeResourceResolver` | ✗ error |
130+
| ResourceResolver not in try-with-resources | `getServiceResourceResolver` in files WITHOUT `try (ResourceResolver` | ⚠ warn |
131+
| Path-bound servlet (bypasses ACLs) | `sling.servlet.paths` | ⚠ warn |
132+
| 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 |
133+
| Deprecated SCR annotations | `import org.apache.felix.scr.annotations` | ⚠ warn |
134+
| Hardcoded AEM paths | String literals matching `/content/dam/`, `/content/` followed by a specific site name, or `/apps/` | ⚠ warn |
135+
| JCR Session direct access | `.adaptTo(Session.class)` outside test files | ⚠ warn |
136+
| Absolute resource type in HTL | `resourceType='/apps/` in `*.html` files | ⚠ warn |
137+
138+
**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`.
139+
118140
## 4. Print Results
119141

120142
Use this exact format with status indicators:
@@ -161,6 +183,14 @@ Component coverage ✓ N/M have FE files
161183
Brand overrides ✓ N brands, no orphans
162184
...
163185
186+
Code Anti-Patterns Status
187+
─────────────────────────────────────────────────────────
188+
Scheduler API (use Sling Jobs) ✓ none found
189+
Static ResourceResolver ✗ 2 hits
190+
MyService.java:15, AnotherService.java:42
191+
Administrative resolver ✓ none found
192+
...
193+
164194
Summary: X passed, Y warnings, Z errors
165195
```
166196

@@ -186,11 +216,13 @@ End with a summary line:
186216

187217
## Examples
188218

189-
1. `/aem-doctor` — Runs all health checks: verifies 45 component definitions match source XML, validates OSGi configs exist, checks dispatcher rules for proper cache headers, and confirms content structure paths are accessible. Reports 2 warnings (missing dispatcher rule, stale OSGi config) and 0 errors.
219+
1. `/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.
220+
221+
2. `/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.
190222

191-
2. `/aem-doctor` (AEM not running) — Checks local file structure (component definitions, OSGi configs, dispatcher rules) successfully. Skips AEM instance checks with warning: "AEM not reachable at http://localhost:4502. Skipping instance checks." Reports local-only results.
223+
3. `/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.
192224

193-
3. `/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.
225+
4. `/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.
194226

195227
## Troubleshooting
196228

0 commit comments

Comments
 (0)