| name | aem-doc-gen |
| description | Generate AEM demo documentation — find or create docs page with configured component, capture dialog and website screenshots on QA, write authoring guide. Extends /aem-editorial-guide for automated pipeline use. Invoked by /dx-agent-all Phase 7 and /dx-req-dod. |
| when_to_use | Use when generating AEM documentation for a completed story, when the user says 'generate docs for this component', 'create authoring guide', or after /aem-verify to capture component documentation. |
| argument-hint | [ADO Work Item ID (optional — uses most recent if omitted)] |
| context | fork |
| agent | aem-editorial-guide-capture |
| allowed-tools | ["read","edit","search","write","agent","AEM/*","playwright/*"] |
Platform note: This skill uses context: fork + agent: aem-editorial-guide-capture for isolated execution. If subagent dispatch is unavailable (e.g., VS Code Chat), you may run inline but AEM MCP tools (AEM/*, playwright/*) must be available. If they are not, inform the user: "AEM doc generation requires AEM and Playwright MCP servers. Please use Claude Code or Copilot CLI."
You generate AEM component demo documentation from completed spec files. You find or create a docs page, configure the component, capture dialog and website screenshots, and write an authoring guide with Authoring and Website sections.
1. Locate the Spec Directory
SPEC_DIR=$(bash .ai/lib/dx-common.sh find-spec-dir <work-item-id-if-provided>)
If the script exits with error, ask the user for the work item ID.
Read .ai/config.yaml for:
aem.author-url (defaults to http://localhost:4502)
aem.author-url-qa — QA author URL
aem.publish-url (defaults to http://localhost:4503)
aem.publish-url-qa — QA publisher URL
aem.resource-type-pattern — component resource type pattern
aem.demo-parent-path — parent path for all AI-created demo pages (e.g., /content/brand-a/ca/en/ca/en/demo)
2. Determine Environment
- If
PIPELINE_MODE=true (check via Bash: echo "$PIPELINE_MODE") or caller passes --qa: use aem.author-url-qa and aem.publish-url-qa
- Otherwise: use
aem.author-url and aem.publish-url
- Fall back to local URLs if QA URLs are not configured
Set $AUTHOR_URL and $PUBLISH_URL for the rest of the flow.
3. Read Source Files
Read these files from $SPEC_DIR (all optional):
explain.md — what was implemented (to identify the component)
implement.md — plan steps (component names, file paths)
aem-after.md — post-deployment component state (dialog fields, properties, pages)
aem-before.md — pre-development baseline (fallback if aem-after.md missing)
4. Identify Component
Determine the target component name from spec files, in order of priority:
aem-after.md — component name in header
implement.md — step titles mentioning a component name
explain.md — requirements referencing a specific component
If no component can be identified, print "Cannot identify target component — provide a component name" and STOP.
5. Check Existing Output
- Check if
demo/authoring-guide.md exists in the spec directory
- If it exists and component name matches → print
demo already up to date — skipping and STOP
- If outdated or not found → continue
6. Check AEM Availability
Test AEM connectivity:
curl -sf -o /dev/null -w "%{http_code}" "$AUTHOR_URL/libs/granite/core/content/login.html" || echo "unreachable"
The author instance has no HTTP Basic Auth — the login page above is reachable directly (it returns the AEM login form, which is filled later with the AEM_INSTANCES creds). Basic Auth (.claude/rules/qa-basic-auth.md / .ai/config.yaml aem.qa-basic-auth) applies only to the QA/Stage publisher — use it if/when probing a published-site URL:
curl -sf -o /dev/null -w "%{http_code}" -u "$QA_USER:$QA_PASS" "$PUBLISH_URL/<published-page>.html" || echo "unreachable"
If unreachable:
- Print:
AEM instance at <url> is not available — generating text-only guide (no screenshots).
- Skip to step 11 (write guide without screenshots)
7. Find Existing Pages
Use the aem-inspector agent to query AEM for pages using this component's resourceType:
Find all pages using component <component-name> (resourceType: <resource-type>). Return the first 5 page paths with full author URLs.
Save the list for the authoring guide. These are existing production/content pages — useful reference for editors.
8. Page Structure Discovery
Check $SPEC_DIR/demo/page-structure.md cache first. If cached and still valid, use it.
If not cached, discover from the first existing page (from step 7) or from aem-after.md:
Use the aem-inspector agent:
Discover page structure from <page-path>:
- Language root (handle doubled country/lang/country/lang pattern)
- Template used by the page
- Container chain from jcr:content/root to the component
Save findings to $SPEC_DIR/demo/page-structure.md
9. Select or Create Demo Page
Read shared/demo-page-setup.md for the Page Selection Rule.
Key rule: New pages are ONLY for new components. For updates to existing components (enhancements, a11y fixes), find the best representative existing page with the component and reuse it. Only create a new page if the component is truly new and not on any existing page.
Priority order for page selection:
- aem-verify output — check
aem-after.md for a "Test Page" or "Demo Page" path. If found, reuse it.
- Existing production page — search for pages with the component. Pick the best representative (prominent usage, same market/brand).
- Create new — only if component is new. Create at
<demo-parent-path>/<feature-title-slug>.
Read aem.demo-parent-path from .ai/config.yaml. If not set, fall back to <language-root>/demo.
Use the aem-inspector agent:
Create a demo page at <demo-parent-path>/<slug> using template <template>.
Recreate the container chain: <chain from page-structure.md>.
Add component <component-name> and configure it with real data from an existing authored instance (search via AEM MCP). Use aem-after.md or implement.md values only as fallback for fields with no real data.
If the page already exists, reuse it (idempotent). Same JCR path works on both local and QA — just use the appropriate author URL.
10. Dialog Screenshot (Author)
Use the aem-editorial-guide-capture agent:
- Navigate to
$AUTHOR_URL/editor.html<docs-page-path>.html
- QA Basic Auth handled by agent if URL is non-localhost
- Handle AEM login redirect if needed
- Open the component dialog via Granite API
- Screenshot the dialog → save as
$SPEC_DIR/demo/dialog-<component>.png
- Close dialog
11. Publish + Website Screenshot
Skip if AEM was unavailable (step 6) or if $PUBLISH_URL is not configured.
11a. Activate the docs page
Use the aem-inspector agent:
Publish the page at <docs-page-path> using mcp__plugin_dx-aem_AEM__activatePage.
11b. Wait for publisher
Poll the publisher URL for a 200 response, up to 60s timeout:
for i in $(seq 1 12); do
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -u "$QA_USER:$QA_PASS" "$PUBLISH_URL<docs-page-path>.html" 2>/dev/null)
[ "$STATUS" = "200" ] && break
sleep 5
done
If still not available after 60s, skip website screenshot and note in guide.
11c. Capture rendered component
Use the aem-editorial-guide-capture agent in publisher view mode:
- Navigate to
$PUBLISH_URL<docs-page-path>.html
- QA Basic Auth handled by agent if URL is non-localhost
- Locate the component by CSS class/custom element tag
- Scroll to component
- Screenshot → save as
$SPEC_DIR/demo/rendered-<component>.png
12. Write Authoring Guide
Write $SPEC_DIR/demo/authoring-guide.md:
# <Component Name> — Authoring Guide
## Existing Pages
| # | Page | Author URL |
|---|------|------------|
| 1 | <page-path> | <full author URL> |
| 2 | ... | ... |
...up to 5
## Authoring
### What Changed
<1-3 sentences explaining what's new in plain English, no code references.
Pull from explain.md and implement.md.>
### How to Use
<Per-field descriptions from aem-after.md dialog fields.
For each field: what it does, when to use it, any conditional visibility.>
### Tips
- <Any conditional visibility: "Enable X to reveal additional fields">
- <Any gotchas: "Leave blank to use the default value">
- <Any recommendations: "Use short titles (under 50 characters) for best display">
### Dialog Screenshot

**Author URL:** <author editor URL to docs page>
## Website
### Rendered Component

**Publisher URL:** <publisher URL to docs page>
Writing principles (same as /aem-editorial-guide):
- No JCR properties, no code paths, no Java class names
- Write for someone who authors pages in AEM, not a developer
- Focus on what they see in the dialog and what each field controls
- Mention any show/hide behavior
If AEM was unavailable (step 6), omit the Screenshots and Website sections and add a note: "Screenshots unavailable — AEM instance was not reachable during documentation generation."
If publisher screenshot failed (step 11), omit the Website section and add a note: "Website screenshot unavailable — publisher did not respond within timeout."
13. Present Summary
## aem-doc-gen complete
**Component:** <name>
**Docs Page:** <page path>
**Environment:** <local / QA>
**Output:**
- `demo/authoring-guide.md`
- `demo/dialog-<component>.png` (if captured)
- `demo/rendered-<component>.png` (if captured)
- `demo/page-structure.md` (if discovered)
**Existing Pages:** <count> found
**Author URL:** <url>
**Publisher URL:** <url>
**AEM:** <connected / unavailable>
Examples
-
/aem-doc-gen hero 2416553 — Finds the spec directory for story #2416553, discovers demo/authoring-guide.md from a prior /aem-editorial-guide run. Connects to AEM, locates or creates a docs page with the hero component configured, captures dialog and rendered screenshots on QA, and writes the enhanced authoring guide with field descriptions, screenshots, and publisher URLs.
-
/aem-doc-gen card (no prior demo) — No existing demo/authoring-guide.md found. Runs the full flow: finds the card component on AEM, captures dialog structure, takes screenshots, and generates the authoring guide from scratch. Saves to the most recent spec directory.
-
/aem-doc-gen productlisting 2416553 (AEM unavailable) — AEM author is not reachable. Degrades gracefully to text-only mode: reads dialog XML from source, generates an authoring guide without screenshots. Notes "AEM unavailable — screenshots not captured" in the output.
Troubleshooting
-
"No spec directory found"
Cause: No spec directory exists for the given work item ID.
Fix: Run /dx-req <id> first to create the spec directory, or provide the correct work item ID.
-
Screenshots captured but images are dark or empty
Cause: The component requires specific content/configuration to render, or the page hasn't fully loaded.
Fix: Pre-configure the component on the demo page with sample content, then re-run. The skill will capture whatever is currently rendered.
-
"AEM unavailable — screenshots not captured"
Cause: AEM author instance is not running or not reachable.
Fix: Start AEM or check aem.author-url in .ai/config.yaml. The text-only guide is still useful — re-run with AEM available to add screenshots later.
Rules
- Read config for all AEM URLs — never hardcode
localhost:4502 or component paths
- QA by default in pipeline — when
PIPELINE_MODE=true, always use QA URLs
- Degrade gracefully — text-only guide if AEM unavailable, still valuable
- Re-use agents — aem-editorial-guide-capture for screenshots, aem-inspector for page creation and JCR operations
- Idempotent — check existing before regenerating; reuse docs page if it exists
- Non-technical audience — authoring guide is for content editors, not developers
- Don't block on screenshots — if dialog won't open or component isn't found, write guide from spec files only and note the issue
- Cache page structure — write
demo/page-structure.md to avoid re-discovery on subsequent runs
- Publish wait — retry loop polling publisher URL, max 60s. Not a fixed sleep.