---
name: aem-component
description: Find all source files, AEM pages, and dialog fields for an AEM component. Use when a developer asks "where is component X?", "what files for hero?", or any component lookup question.
when_to_use: "Use when a developer asks 'where is component X?', 'what files for hero?', 'show me the banner component', or any component lookup. Also trigger on 'find component', 'locate component', 'component files'."
argument-hint: "[component name (e.g., hero, banner, accordion)]"
allowed-tools: ["read", "edit", "search", "write", "agent", "ado/*", "AEM/*", "playwright/*"]
---

You receive a component name and produce a complete developer reference — every source file, AEM page, and dialog field for that component.

**Performance target:** ~10-15 tool calls total. No unnecessary agents or MCP calls.

## 1. Parse Input & Normalize

The argument is a component name. Accept any format and generate **all search variations**.

### Step 1a: Extract base name

Strip resource type prefixes:
- `project/components/content/hero` → `hero`
- `myapp/base/components/myapp-banner` → `myapp-banner`

Read `.ai/config.yaml` for `aem.component-prefix` to know the project's naming prefix.

### Step 1b: Generate search variations (enhanced with project.yaml)

From the base name, generate a **regex pattern** for grep that covers all naming conventions:

Given input `{name}`:

1. **As-is**: `{name}`
2. **Remove hyphens/spaces**: `my-component` → `mycomponent`
3. **Add hyphens at word boundaries**: `mycomponent` → `my-component`
4. **Project prefix**: `<prefix>-{name}` (from `aem.component-prefix`)
5. **Strip prefixes**: `prefix-hero` → also search `hero`

**If `.ai/project/project.yaml` exists:** Read `platforms[].component-prefixes` for additional prefix variations. For each prefix, generate `{prefix}{name}` as an additional variation. Example: prefixes `[mycomp-, mycomp-bff-, canada-, corp-]` → also search `mycomp-{name}`, `mycomp-bff-{name}`, `canada-{name}`, `corp-{name}`.

Build a single grep regex covering all variations.

If no argument provided, ask the user for the component name.

## 2. Search Local Docs (DIRECT — no agent)

**Do NOT spawn an agent for this.** Use direct Grep/Read calls — it's just 2-4 files.

Run these Grep calls **in parallel** (all variations in one regex pattern):

1. **Grep** `.ai/project/component-index.md` for all variations — the local repo component index (generated by `/aem-init`)
2. **Grep** `.ai/project/component-index-project.md` for all variations — the cross-repo enriched component catalog (if it exists)
3. **Read** `.ai/config.yaml` for project structure details — repos, component paths, SCM URLs

From `component-index-project.md` extract (if found):
- **Platform** column — your project's platform identifiers (e.g. `alpha`, `beta`), or both (determines which file patterns to use)
- **FE** column — `B`, `C`, `B C`, `Yes`, `N/A` (determines which FE repos/paths to search)
- **Source Link** — ADO URL containing the exact component path (critical for platforms that resolve the base path from the Source Link)
- **Repo** column — which repo the component lives in
- **Notes** — category info (BFF, Commerce, Form, etc.)

**If Component Details section exists** for this component in `component-index-project.md`: extract dialog fields, Java models, clientlib info. These serve as fallback when AEM MCP is unavailable.

## 3. Build Source File URLs

### With file-patterns.yaml (preferred — data-driven resolution)

If `.ai/project/file-patterns.yaml` exists, spawn **ONE aem-file-resolver agent** with:
- `component_name` — the confirmed component name from step 2
- `platform` — detected platform(s) from the index match
- `fe_locations` — FE column value from `component-index-project.md`

The agent reads `file-patterns.yaml`, resolves all files per platform, and returns a structured file table with ADO URLs.

**Multi-platform support:** If the component exists on multiple platforms (e.g., two platforms `alpha` and `beta`), the agent resolves files for EACH platform separately and returns separate Backend sections.

### Without file-patterns.yaml (convention-based fallback)

Read `.ai/config.yaml` for:
- `scm.org` and `scm.project` — for building SCM URLs
- `aem.component-path` — component definition root
- `aem.frontend-dir` — frontend source root (if applicable)
- `repos:` — for cross-repo file resolution

**SCM URL pattern** — Build URLs from the SCM config. For ADO:
```
https://<scm.org>.visualstudio.com/<scm.project-url-encoded>/_git/<REPO>?path=/<FILE_PATH>
```

Or read `ado.org` from `project.yaml`:
```
https://{ado.org}/{ado-project}/_git/{repo}?path=/{FILE_PATH}
```

**Apps files** — Use `aem.component-path` to derive:

| File | Derived Path |
|------|-------------|
| HTL template | `<component-path>/<name>/<name>.html` (or versioned: `<name>/v1/<name>/<name>.html`) |
| Dialog | `<component-path>/<name>/_cq_dialog/.content.xml` (or versioned path) |
| Component def | `<component-path>/<name>/.content.xml` |

**Verify with Glob** — don't assume the exact path pattern. Glob for `**/<name>/**/*.html` and `**/<name>/**/.content.xml` to confirm.

**Frontend files** — Use `aem.frontend-dir` to locate JS/SCSS/config:

| File | Pattern |
|------|---------|
| JS | `<frontend-dir>/**/components/<name>/*.<name>*.js` |
| SCSS | `<frontend-dir>/**/components/<name>/*.<name>*.scss` |
| Config | `<frontend-dir>/**/components/<name>/*.<name>*.config.js` |

**Java/backend files** — Grep for the component name in Java source:
```
Grep: {name}
path: <java-source-root>
glob: "*.java"
```

**Only use ADO code search (`mcp__ado__search_code`) as a LAST RESORT** — if a component isn't in the docs at all and conventions don't apply.

## 4. Find AEM Pages

### With project.yaml (market-scoped search)

If `.ai/project/project.yaml` exists:
- Read active brands/markets from `project.yaml` to get AEM content paths
- Pass `primary_language_only: true` to aem-page-finder (reduces MCP calls)
- If the component has a market-specific prefix (e.g., `canada-`), scope the search to matching markets only

### Without project.yaml (config-based search)

Read `.ai/config.yaml` `aem.content-paths` for configured content paths.

### Spawn aem-page-finder

Spawn **ONE aem-page-finder agent** (model: haiku). Pass it:
- The **exact component name(s)** found in step 2
- The **content paths** (from project.yaml markets or config.yaml)
- The **author URL** (from `project.yaml` → `defaults.qa-author-url` or config.yaml → `aem.author-url-qa`)
- `primary_language_only: true` (from content-paths.yaml or default)

Run this agent in parallel with source file resolution (step 3).

## 5. Inspect Dialog (optional, if AEM available)

### Primary: AEM MCP (live dialog)

If AEM MCP is reachable, read the dialog structure:
- Use `mcp__plugin_dx-aem_AEM__getNodeContent` on the `_cq_dialog` path with depth 6
- Extract: field names, field types, labels, default values
- Present as a compact table

### Fallback: Component Details from index

If AEM is not reachable BUT Component Details section exists in `component-index-project.md` for this component (from step 2): display those dialog fields as fallback.

If neither source is available, note "Dialog fields not available — no AEM MCP and no Component Details in index".

## 6. Present Results

```markdown
## Component: <name>

**Resource type:** `<resource-type>`
**Platform:** <platform identifier, e.g. alpha | beta | both>
**FE:** <B | C | B C | Yes | N/A>

---

### Source Files

**Backend — <repo> (<platform>)**
| File | Purpose | Link |
|------|---------|------|
| `<name>.html` | HTL template | [link](url) |
| `_cq_dialog/.content.xml` | Author dialog | [link](url) |
| `.content.xml` | Component definition | [link](url) |
| `<Name>Model.java` | Sling Model | [link](url) |
| `<Name>ModelTest.java` | Unit test | [link](url) |

<If multi-platform, show separate Backend sections per platform>

**Frontend — <repo> (<brand|core>)**
| File | Purpose | Link |
|------|---------|------|
| `<name>.js` | Component logic | [link](url) |
| `<name>.scss` | Styles | [link](url) |
| `<name>.hbs` | Template (Legacy only) | [link](url) |

### Dialog Fields
| Field | Type | Label | JCR Property |
|-------|------|-------|-------------|
| ... | ... | ... | ... |

<Note source: "(from AEM MCP)" or "(from Component Details fallback)">

### AEM Pages
| Page | Market | Author URL |
|------|--------|-----------|
| <page-name> | <market> | [link](url) |

<Group by market/language when market-scoped search was used>

### Notes
<Naming mismatches, shared FE, missing files, edge cases, category info>

---

**Save results to a file?** (suggested: `.ai/research/<name>.md`)
```

## 7. Save (if user confirms)

If the user says yes:
- **Default location:** `.ai/research/<name>.md`
- Create the `.ai/research/` directory if it doesn't exist
- Confirm path after saving

## Examples

### Simple component lookup
```
/aem-component hero
```
Finds all source files for the `hero` component — HTL, dialog XML, Java model, JS, SCSS. Shows dialog fields from AEM MCP (or index fallback). Lists top AEM pages using it with author URLs.

### With project prefix
```
/aem-component myprefix-banner
```
Strips the prefix, searches for both `banner` and `myprefix-banner` variations. Resolves files using `file-patterns.yaml` if available.

### Multi-platform component
```
/aem-component card
```
If `card` exists on two platforms (e.g. `alpha` and `beta`), shows separate Backend sections for each with platform-specific file paths and ADO links.

## Troubleshooting

### "Component not found in index"
**Cause:** Component is new (not yet in seed data) or uses an unexpected naming convention.
**Fix:** Run `/aem-refresh` to update seed data. Or check the component name — try without prefix, with hyphens removed, or with different prefix variations.

### No AEM pages found
**Cause:** Component isn't authored on any pages, or content paths in config don't cover the right site.
**Fix:** Check `.ai/config.yaml` `aem.content-paths` covers the target site. The component may only exist in a market not listed in `aem.active-markets`.

### Dialog fields show "not available"
**Cause:** AEM MCP server is not running or unreachable.
**Fix:** Start AEM locally (`http://localhost:4502`). If AEM is unavailable, the skill falls back to Component Details from `component-index-project.md` if available.

## Rules

- **Docs first** — always check both `component-index.md` AND `component-index-project.md` before any MCP call
- **Data-driven when possible** — use file-patterns.yaml via aem-file-resolver agent when available, fall back to convention-based Glob when not
- **Every seed data file is optional** — missing file = skip that capability gracefully, no errors
- **TWO agents max** — aem-file-resolver (if file-patterns.yaml exists) + aem-page-finder. Everything else is direct tool calls.
- **Normalize names** — handle hyphens, spaces, prefixes gracefully. Use project.yaml component-prefixes for additional variations.
- **Multi-platform** — if component exists on multiple platforms, resolve files for EACH platform separately. Present as separate Backend sections.
- **Clickable links** — all file paths as SCM/ADO URLs, all pages as AEM author URLs
- **No guessing** — if a file isn't found, say "Not found" not "probably exists at..."
- **FE naming gotcha** — if FE search returns nothing, check HTL `data-component-name` attribute; another component may share the FE code
- **Dialog fallback** — use Component Details from index when AEM MCP is unavailable
- **Ask to save** — always ask before writing files
