[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6H3YYA8QPD409GSC1PMVSN5":3,"skill-same:01M6H3YYA8QPD409GSC1PMVSN5":80},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":47,"linkOnly":48,"markdownContent":49,"markdownBody":50,"frontMatter":51,"refName":57,"commitSha":58,"skillDirectory":59,"forksCount":60,"repositoryHtmlUrl":61,"repositoryHomepageUrl":6,"ownerHtmlUrl":62,"ownerBlogUrl":63,"ownerDescription":64,"updatedAt":65,"install":66,"resources":79},"01M6H3YYA8QPD409GSC1PMVSN5","aem-init",null,"Configure AEM-specific settings for the dx workflow. Detects AEM project structure, component paths, and brands. Appends aem section to .ai\u002Fconfig.yaml. Run after \u002Fdx-init.","easingthemes\u002Fdx-aem-flow","easingthemes","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F2750284?v=4","01M6H3XYGJY8QCX9ES36P2WF4H","Dragan Filipović","01M6H3XYMN1XVSGKN7N79SW3RH",7,"MIT","https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-aem\u002Fskills\u002Faem-init\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"aem init","init","settings","playwright","interactive","dx","for","paths","edit","config","write","read","run","project structure","component","structure","workflow","configure","search","project","2026-11-10 10:12:30",false,"---\nname: aem-init\ndescription: \"Configure AEM-specific settings for the dx workflow. Detects AEM project structure, component paths, and brands. Appends aem section to .ai\u002Fconfig.yaml. Run after \u002Fdx-init.\"\nargument-hint: \"(no arguments — interactive)\"\nallowed-tools: [\"read\", \"edit\", \"search\", \"write\", \"agent\", \"AEM\u002F*\", \"playwright\u002F*\"]\n---\n\nYou configure AEM-specific settings by detecting the project structure and appending an `aem:` section to `.ai\u002Fconfig.yaml`.\n\n## Re-run Validation Protocol\n\n**CRITICAL: When aem-init is re-run, EVERY step MUST execute. NEVER stop early.** If the user chooses \"Keep as-is\" for config, skip to step 6 and continue through ALL remaining steps (6→7→8→9). Each step validates:\n\n| File Category | Re-run Behavior |\n|---|---|\n| **Config** (aem: section in config.yaml) | Ask: keep \u002F modify \u002F regenerate |\n| **Component index** (.ai\u002Fproject\u002Fcomponent-index.md) | Offer to re-scan if stale |\n| **Component discovery** (.ai\u002Fproject\u002Fcomponent-discovery.md) | Offer to re-scan if stale (AEM dialog changes on QA) |\n| **Shared rule extensions** (pr-review.md, pr-answer.md AEM sections) | Validate sections exist, re-append if missing |\n| **Rule templates** (.claude\u002Frules\u002Fbe-*.md, fe-*.md) | Compare against plugin template → if template changed and user hasn't customized: update. If user customized: show diff, ask |\n| **Copilot instructions** | Copilot CLI v1.0.89+ reads `.claude\u002Frules\u002F` natively — no copies, no env var |\n| **Copilot agents** (.github\u002Fagents\u002FAEM*.md) | Compare against plugin template → update silently if changed |\n\n> **Inline execution from dx-init:** When this skill is run inline from `\u002Fdx-init` step 7 (AEM auto-chain), skip Copilot-related steps: **8a** (Copilot question), **8e** (AEM Copilot agent templates), and **8f** (copilot-instructions.md update). Also skip **step 9** (Confirm). These are handled by dx-init steps 9 and 10 instead. Set `COPILOT_ENABLED=false` as default — dx-init handles Copilot output separately.\n\n## 1. Check Prerequisites\n\nCheck if `.ai\u002Fconfig.yaml` exists. If not: \"Run `\u002Fdx-init` first to set up the base project config.\"\n\nCheck if `.ai\u002Fconfig.yaml` already has an `aem:` section:\n- **If it exists:** Display current AEM config and ask: \"AEM config already exists. **(A) Keep as-is**, **(B) Modify**, or **(C) Regenerate**?\"\n  - If **A**: Say \"Config kept. Validating all AEM files...\" — then **CONTINUE to step 6** to validate component index, rules, and templates. **DO NOT stop or exit.**\n  - If **B\u002FC**: Continue to step 2\n- **If it doesn't exist:** Continue to step 2.\n\n## 2. Detect AEM Structure\n\n### 2a. Find Component Path\n\nSearch for AEM component definitions using Glob (no Bash needed):\n\n```\nGlob: \"**\u002Fjcr_root\u002Fapps\u002F*\u002Fcomponents\u002F*\u002F.content.xml\"\n```\n\nFrom the results, extract:\n- **Component namespace** — e.g., `\u002Fapps\u002Fmyproject\u002Fcomponents\u002Fcontent\u002F`\n- **Component prefix** — e.g., `myproject` from path patterns\n- **Component group** — from `componentGroup` in `.content.xml` files\n\n### 2b. Detect Module Structure\n\nLook for AEM Maven modules:\n\n| Check | Module Type |\n|-------|------------|\n| `*-core\u002Fpom.xml` with `bundle` packaging | Java\u002FOSGi bundle |\n| `*-apps\u002Fpom.xml` with `content-package` | HTL + dialogs |\n| `*-clientlibs*\u002Fpom.xml` or `frontend\u002F` | Frontend build |\n| `*-config*\u002Fpom.xml` | Configuration |\n| `*-all*\u002Fpom.xml` | Deployable container |\n\n### 2c. Detect Frontend Structure\n\nLook for frontend source locations using Glob (no Bash needed):\n\n```\nGlob: \"*\u002Ffrontend\u002F\"\nGlob: \"**\u002Fui.frontend\u002F\"\nGlob: \"**\u002Fclientlib.config.js\"\nGlob: \"**\u002Fclientlibs\u002F**\u002F.content.xml\"\n```\n\n### 2d. Detect Brands (multi-brand)\n\nLook for brand directories using Glob (no Bash needed):\n\n```\nGlob: \"**\u002Fbrands\u002Fclientlibs\u002F*\u002F\"\n```\n\n## 3. Ask AEM URLs\n\nAsk all four URLs. Author = content editing and dialog testing. Publisher = user-facing website rendering. These are always different instances.\n\n```\n**AEM Author URL (local dev)?** Content editing, dialog testing, component configuration. (default: http:\u002F\u002Flocalhost:4502)\n**AEM Publisher URL (local dev)?** User-facing website rendering. (default: http:\u002F\u002Flocalhost:4503)\n**Remote Author URL (QA\u002Fstage)?** For clickable author links in research output. (leave blank to use dev URL)\n**Remote Publisher URL (QA\u002Fstage)?** For user-facing verification on QA environment. (leave blank to use dev URL)\n```\n\n## 4. Confirm\n\nPresent detected values:\n\n```markdown\n## Detected AEM Configuration\n\n| Property | Value |\n|----------|-------|\n| Component Path | `\u002Fapps\u002F\u003Cprefix>\u002Fcomponents\u002Fcontent\u002F` |\n| Component Prefix | `\u003Cprefix>` |\n| Component Group | `\u003Cgroup>` |\n| Resource Type Pattern | `\u003Cprefix>\u002Fcomponents\u002Fcontent\u002F\u003Cname>` |\n| Java Package | `\u003Cpackage>` (if detected) |\n| Frontend Dir | `\u003Cpath>` |\n| Brands | \u003Clist or \"single-brand\"> |\n| AEM Author (Dev) | `http:\u002F\u002Flocalhost:4502` |\n| AEM Publisher (Dev) | `http:\u002F\u002Flocalhost:4503` |\n| AEM Author (QA) | `\u003Curl or \"same as dev\">` |\n| AEM Publisher (QA) | `\u003Curl or \"same as dev\">` |\n\n**Correct?** Type \"yes\" or tell me what to change.\n```\n\n## 5. Append to Config\n\nAppend `aem:` section to `.ai\u002Fconfig.yaml`:\n\n```yaml\naem:\n  component-path: \"\u002Fapps\u002F\u003Cprefix>\u002Fcomponents\u002Fcontent\"\n  component-prefix: \"\u003Cprefix>\"\n  component-group: \"\u003Cgroup>\"\n  resource-type-pattern: \"\u003Cprefix>\u002Fcomponents\u002Fcontent\u002F\u003Cname>\"\n  java-package: \"\u003Cpackage>\"              # if detected\n  frontend-dir: \"\u003Cpath>\"                 # if detected\n  brands: [\u003Clist>]                       # if multi-brand\n  author-url: \"http:\u002F\u002Flocalhost:4502\"    # Author — dialog\u002Fcomponent editing\n  author-url-qa: \"\u003Curl>\"                 # Remote author — clickable links in research output\n  publish-url: \"http:\u002F\u002Flocalhost:4503\"   # Publisher — user-facing website\n  publish-url-qa: \"\u003Curl>\"               # Remote publisher — user-facing verification on QA\n  demo-parent-path: \"\u003Cpath>\"             # Parent for AI-created demo pages (e.g., \u002Fcontent\u002Fmysite\u002Fen\u002Fdemo)\n  # selector: \"\u003Cexporter-selector>\"      # Uncomment if project uses custom selector\n```\n\n## 6. Component Discovery\n\n### 6a. Glob-based Component Index (structural)\n\nAsk: \"Scan for existing components and generate `.ai\u002Fproject\u002Fcomponent-index.md`? This helps `\u002Faem-component` and `\u002Fdx-ticket-analyze` find files faster.\"\n\nIf yes:\n1. Glob for all component `.content.xml` files under the component path\n2. Extract: name, title, group, resource type, resourceSuperType\n3. Write `.ai\u002Fproject\u002Fcomponent-index.md` as a lookup table (create `.ai\u002Fproject\u002F` if needed)\n\n### 6b. AEM MCP Component Discovery (semantic)\n\nAsk: \"Query AEM QA for component dialog fields, variants, and pages? This creates `.ai\u002Fproject\u002Fcomponent-discovery.md` for richer AI planning. Requires AEM QA to be reachable.\"\n\nIf yes:\n\n**Prerequisites check:**\n1. `aem.author-url-qa` must be configured. If not: warn \"Set `aem.author-url-qa` in config to enable component discovery.\" and skip.\n2. Test AEM QA reachability: `mcp__plugin_dx-aem_AEM__getNodeContent` on the component root path. If unreachable: warn \"AEM QA not reachable — component-discovery.md skipped. Run `\u002Faem-init` again when QA is available.\" and skip.\n\n**Discovery logic:**\n\nFor each component found by Step 6a's Glob scan (scoped to this repo's `aem.component-path`):\n\n1. **Dialog fields** — `mcp__plugin_dx-aem_AEM__getNodeContent` on `\u003Ccomponent-path>\u002F\u003Cname>\u002F_cq_dialog` with depth 6. Extract: field name, `sling:resourceType` (maps to field type), `fieldLabel`, `fieldDescription`, `required` flag.\n\n2. **Variants in this repo** — Glob sibling directories with same name suffix under the component path. E.g., if component is `productcard`, check for `*-productcard` or `productcard-*` siblings.\n\n3. **Variants in other repos** — `mcp__plugin_dx-aem_AEM__searchContent` for components whose `sling:resourceSuperType` equals this component's resourceType. Cross-reference with `repos:` section in config.yaml to note owning repo.\n\n4. **Pages using component** — `mcp__plugin_dx-aem_AEM__searchContent` by `sling:resourceType` under the content roots from `content-paths.yaml` or `aem.demo-parent-path` parent. Limit to 5 pages.\n\n5. **Authored values** — For the first page found, `mcp__plugin_dx-aem_AEM__getNodeContent` on the component instance (depth 4). Extract actual field values to reveal semantic meaning.\n\n**Parallelism:** Dispatch one Explore agent per ~10 components. Each agent receives the component list, AEM QA URL, and query instructions. Agents use `mcp__plugin_dx-aem_AEM__*` tools directly.\n\n**Output:** Write `.ai\u002Fproject\u002Fcomponent-discovery.md` with format:\n\n```markdown\n# AEM Component Discovery\n\n**Generated:** \u003Cdate>\n**Instance:** \u003Caem.author-url-qa> (QA)\n**Repo:** \u003Cscm.repo or project name>\n**Scope:** \u003Caem.resource-type-pattern>* (\u003Ccount> components)\n\n## \u003Ccomponent-name>\n\n**Resource Type:** \u003Cfull resource type>\n**Owner:** \u003Crepo name> (this repo)\n**Variants (this repo):** \u003Ccomma-separated list or \"none\">\n**Variants (other repos):**\n  - `\u003Cvariant-name>` → \u003Crepo-name> (superType: \u003Cthis component's resourceType>)\n\n### Dialog Fields\n| Field | Type | Label | Description | Required |\n|-------|------|-------|-------------|----------|\n| \u003Cname> | \u003Ctype> | \u003CfieldLabel> | \u003CfieldDescription> | \u003Cyes\u002Fno> |\n\n### Sample Authored Values (from \u003Cpage-path>)\n| Field | Value |\n|-------|-------|\n| \u003Cname> | \u003Cvalue or \"(empty)\"> |\n\n### Pages (\u003Ccount>)\n- \u003Cpage-path-1>\n- \u003Cpage-path-2>\n...\n\n### Cross-Repo Dependencies\n- **superType:** \u003CsuperType resource type> → \u003Crepo name> (base)\n```\n\nFor brand-override repos: dialog fields note `inherited from \u003Cbase>` vs `LOCAL (this repo)`.\n\n**Re-run behavior:** If `.ai\u002Fproject\u002Fcomponent-discovery.md` already exists, ask \"Re-scan component discovery? (recommended after dialog changes on QA)\". If no: keep existing, report \"validated (kept existing)\".\n\n## 7. Extend Shared Rules with AEM Patterns\n\nAppend AEM-specific focus areas to the shared rules in `.ai\u002Frules\u002F` (installed by dx-init). This ensures both local dx skills and automation agents apply AEM review criteria.\n\n**Idempotent:** check if the section already exists before appending.\n\n### 7a. Extend pr-review.md\n\nIf `.ai\u002Frules\u002Fpr-review.md` exists:\n\n1. Read the file and check if it contains `## AEM\u002FSling Patterns` (use Grep tool, not Bash)\n2. If NOT found, append:\n\n```markdown\n\n## AEM\u002FSling Patterns\n- Verify Sling Model annotations: correct adaptables, resource types, injection strategies\n- Check @Self @Via(ResourceSuperType) delegation patterns\n- Validate OSGi service references use proper injection\n- Ensure ResourceResolver lifecycle is respected (no leaked resolvers)\n\n## Frontend Patterns\n- Check component-loader registration matches class name\n- Verify config files externalize DOM selectors and CSS classes\n- Check PubSub event usage matches constants from commons\u002Fconstants\u002Fevents.js\n- Validate SCSS uses @use\u002F@forward (not @import)\n```\n\n### 7b. Extend pr-answer.md\n\nIf `.ai\u002Frules\u002Fpr-answer.md` exists:\n\n1. Read the file and check if it contains `## AEM\u002FSling Patterns` (use Grep tool, not Bash)\n2. If NOT found, append:\n\n```markdown\n\n## AEM\u002FSling Patterns\n- Understand @Self @Via(ResourceSuperType) delegation\n- Understand Sling Model injection strategies\n- Know when OSGi service patterns are intentional\n\n## Frontend Patterns\n- Understand component-loader registration\n- Know config externalization patterns\n- Understand PubSub event communication\n- SCSS uses @use\u002F@forward (not @import)\n```\n\nIf `.ai\u002Frules\u002Fpr-review.md` or `.ai\u002Frules\u002Fpr-answer.md` does not exist, skip and note: \"Shared rules not found — run `\u002Fdx-init` first.\"\n\n## 8. Copy Convention Templates\n\nUnified convention templates (`templates\u002Frules\u002F`) contain dual frontmatter (`paths:` for Claude Code, `applyTo:` for Copilot CLI). Each template is copied to `.claude\u002Frules\u002F`. Copilot CLI v1.0.89+ reads rules from this same location natively and maps `paths:` to its scope — no `.github\u002Finstructions\u002F` copies, no env var.\n\n### 8a. Ask about Copilot support\n\n```\n**Support GitHub Copilot CLI?** (default: yes)\nIf yes:\n- AEM Copilot agent definitions are generated in `.github\u002Fagents\u002F`\nIf no:\n- No Copilot agents generated\n```\n\nSet `COPILOT_ENABLED=true` or `COPILOT_ENABLED=false` based on the answer.\n\n### 8b. Create target directories\n\nEnsure `.claude\u002Frules\u002F` exists. The Write tool creates parent directories automatically, so no explicit mkdir is needed.\n\n### 8c. Copy rule templates to `.claude\u002Frules\u002F`\n\n1. Read `project.role` from `.ai\u002Fconfig.yaml`\n2. Determine which template directories to install:\n\n| `project.role` | Directories |\n|---|---|\n| `frontend` | `shared\u002F` + `fe\u002F` |\n| `backend` | `shared\u002F` + `be\u002F` |\n| `fullstack` | `shared\u002F` + `be\u002F` + `fe\u002F` |\n| `config` | `shared\u002F` only |\n| (not set) | All directories (backward compatibility) |\n\n3. For each selected directory, Glob template files (no Bash needed):\n```\nGlob: \"\u003Cplugin-path>\u002Ftemplates\u002Frules\u002F\u003Cdir>\u002F*.md.template\"\n```\n\n4. For each template file found:\n\nDerive target filename by stripping the `.template` suffix (e.g., `be-sling-models.md.template` → `be-sling-models.md`).\n\n**If `.claude\u002Frules\u002F\u003Ctarget>` already exists:**\nRead both the existing file and the plugin template. Compare content:\n- **Identical:** Report \"validated (up to date)\", skip.\n- **Template changed, file matches old template:** Update silently — the user hasn't customized it.\n- **User has customized (content differs from template):** Show the diff summary and ask: **(A) Keep existing**, **(B) Replace with updated template**, **(C) Write updated as `.template`** (user can diff manually).\n\n**Check for topic overlap (new files only):**\nScan existing `.claude\u002Frules\u002F*.md` — read their frontmatter (`description` and `paths` fields). Compare against the template's `paths` glob and topic (filename prefix: `fe-` or `be-`). If a file with overlapping paths and similar topic exists:\n\n- Show both filenames and their descriptions side-by-side\n- Ask: **(A) Skip** (keep existing), **(B) Replace** (overwrite with template), **(C) Write as `.template`** (user can diff manually)\n\n**No conflict:**\nCopy the file to `.claude\u002Frules\u002F\u003Ctarget>`, stripping the `.template` extension.\n\n5. Resolve template variables before writing:\n\nRead from `.ai\u002Fconfig.yaml`:\n\n| Variable | Config source |\n|---|---|\n| `{{COMPONENT_PREFIX}}` | `aem.component-prefix` |\n| `{{DAM_PATH}}` | `aem.dam-path` |\n| `{{CSS_PREFIX}}` | `aem.component-prefix` (fallback: `project.prefix`) |\n| `{{BUILD_TOOL}}` | `toolchain.build-tool` |\n| `{{CSS_COMPILER}}` | `toolchain.css-compiler` |\n| `{{NODE_VERSION}}` | `toolchain.node` |\n| `{{COMPONENT_BASE_CLASS}}` | `toolchain.component-base-class` |\n| `{{RESOURCE_TYPE_PATTERN}}` | `aem.resource-type-pattern` |\n\nFor each variable, if the config value is empty or missing, leave the placeholder as-is (consumer will fill in or the value is not relevant for this project).\n\n> **Note:** `.github\u002Finstructions\u002F` copies are no longer generated. Copilot CLI v1.0.89+ reads rules directly from `.claude\u002Frules\u002F`. Rules with dual frontmatter (`paths:` + `applyTo:`) work in both tools from a single source.\n\n### 8d. (Removed — instruction templates merged into rule templates)\n\nInstruction templates no longer exist as separate files. The unified rule templates in `templates\u002Frules\u002F` contain both `paths:` (Claude Code) and `applyTo:` (Copilot CLI) frontmatter. Step 8c handles both outputs.\n\n### 8e. Copy AEM Copilot agent templates (if Copilot enabled)\n\nOnly if the user answered \"yes\" to Copilot support in step 7a.\n\nUse Glob to find agent template files (no Bash needed):\n```\nGlob: \"\u003Cplugin-path>\u002Ftemplates\u002Fagents\u002F*.agent.md.template\"\n```\n\nFor each result:\n\n1. Read the template\n2. Strip the `.template` suffix from the filename\n3. Write to `.github\u002Fagents\u002F\u003CAgentName>.agent.md`\n\n**On re-run:** If `.github\u002Fagents\u002F\u003Ctarget>` already exists, compare against the plugin template. Update silently if the template has changed (Copilot agents are not user-customized). Report \"validated\" or \"updated\".\n\n### 8f. Update copilot-instructions.md (if Copilot enabled and file exists)\n\nIf `.github\u002Fcopilot-instructions.md` exists (generated by `\u002Fdx-init`), append an AEM agents section:\n\n```markdown\n\n## AEM Agents\n\n| Agent | Purpose | Invoke |\n|-------|---------|--------|\n| AEMBefore | Pre-development baseline snapshot | `@AEMBefore \u003Ccomponent>` |\n| AEMAfter | Post-deployment verification | `@AEMAfter \u003Ccomponent>` |\n| AEMSnapshot | Component inspection | `@AEMSnapshot \u003Ccomponent>` |\n| AEMDemo | Dialog screenshot + authoring guide | `@AEMDemo \u003Ccomponent>` |\n| AEMComponent | Find pages using a component | `@AEMComponent \u003Ccomponent>` |\n| AEMVerify | Bug verification on AEM | `@AEMVerify \u003Ccomponent>` |\n```\n\nIf the file doesn't exist, skip this step (it means `\u002Fdx-init` didn't generate Copilot files).\n\n### 8g. Install AEM browser-auth helper (Playwright)\n\nCopy the reusable auth helper so browser agents can authenticate to AEM without the password ever entering the model's context.\n\n1. Copy `..\u002F..\u002Fdata\u002Flib\u002Faem-playwright-auth.sh` (relative to this skill's directory — the dx-aem plugin's `data\u002Flib\u002F`) → `.ai\u002Flib\u002Faem-playwright-auth.sh` (create `.ai\u002Flib\u002F` if missing; `chmod +x`). On re-run, overwrite silently if the plugin version changed.\n2. Ensure the consumer `.gitignore` contains `.ai\u002Fplaywright\u002F` (the helper writes the session cookie + Basic Auth creds there — must never be committed). Append it under the runtime-output block if absent.\n3. **Install the Playwright browser** (one-time): the dx-aem `playwright` MCP server drives a real Chromium that is NOT bundled — without it, every browser skill (`\u002Faem-verify`, `\u002Faem-qa`, `\u002Faem-fe-verify`, `\u002Faem-editorial-guide`) fails at first navigation. Run:\n   ```bash\n   npx playwright install chromium\n   ```\n   It's idempotent (no-op if already present). If it fails (offline\u002Frestricted), tell the user to run it manually before any browser verification.\n\n**What it provides** (two independent auth layers — see the `qa-basic-auth` rule):\n- **AEM author login** → `bash .ai\u002Flib\u002Faem-playwright-auth.sh author \u003Clocal|qa>` writes `.ai\u002Fplaywright\u002Faem-author-state.json` (a Playwright `storageState` with the `login-token` cookie). Browser agents load it via `browser_set_storage_state` before navigating to the author — no form-fill, no password in context.\n- **Publisher Basic Auth** (opt-in) → `bash .ai\u002Flib\u002Faem-playwright-auth.sh config` writes `.ai\u002Fplaywright\u002Fconfig.json` with `httpCredentials` from `QA_BASIC_AUTH_*`. To use it browser-natively, add `\"--config\", \".ai\u002Fplaywright\u002Fconfig.json\"` to the `playwright` server args in `.mcp.json`. (Default skills use URL-embedded Basic Auth, which needs no config.)\n\n### 8h. Report results\n\n```markdown\n### Convention Files\n\n**Rules** (`.claude\u002Frules\u002F`): \u003CN> written, \u003CN> skipped\n\u003CIf Copilot enabled:>\n**Copilot instructions**: Copilot CLI v1.0.89+ reads `.claude\u002Frules\u002F` natively (no copies needed)\n**Copilot Agents** (`.github\u002Fagents\u002F`): \u003CN> written, \u003CN> skipped\n```\n\n## 9. Confirm\n\n```markdown\n## AEM Initialized\n\n**Component Path:** `\u003Cpath>`\n**Brands:** \u003Clist>\n**Config:** `.ai\u002Fconfig.yaml` (aem section appended)\n\n### Next Steps\n- `\u002Faem-component \u003Cname>` — look up a component's files and pages\n- `\u002Faem-snapshot \u003Cname>` — capture baseline before development\n- `\u002Faem-verify \u003Cname>` — verify after deployment\n```\n\n## 10. Project Setup (if seed data exists)\n\nCheck if `.ai\u002Fproject\u002Fproject.yaml` exists. If not, print: \"No project.yaml found. To add project knowledge, create `.ai\u002Fproject\u002Fproject.yaml`. See docs\u002Fauthoring\u002Fseed-data-guide.md for format.\" Then skip to step 11.\n\nIf project.yaml exists:\n\n### 10a. Brand\u002FMarket Selection\n\n1. Read `project.yaml` → `brands[]` list\n2. For each brand:\n   - If `single-market: true`: auto-confirm this brand and its single market. Report \"Auto-confirmed: \u003Cbrand> (\u003Cmarket>)\"\n   - Otherwise: Ask via AskUserQuestion: \"Which markets are active for **\u003Cbrand>**? Options: \u003Cmarket codes>. Enter comma-separated codes or 'all'.\"\n3. Store selected brands and market codes\n\n### 10b. Repo Local Paths\n\n1. Read existing `repos:` from `.ai\u002Fconfig.yaml` (written by `\u002Fdx-init`)\n2. Read `repos[]` from `.ai\u002Fproject\u002Fproject.yaml` for platform and ado-project data\n3. For each repo in project.yaml NOT already in config `repos:`, add it with `name` and `path` (ask: \"Local path for **\u003Crepo>**? (default: `..\u002F\u003Cname>`)\")\n4. For each repo in config `repos:`, enrich with fields from project.yaml: `platform`, `ado-project`\n5. If `path` is missing on any entry, ask: \"Local path for **\u003Crepo>**? (default: `..\u002F\u003Cname>`)\"\n6. Ask for `base-branch` if not set (default: same as `scm.base-branch`)\n7. For each repo in `repos:`, if `role:` is missing or `capabilities:` is present:\n   - Ask via AskUserQuestion: \"What is **\u003Crepo>**'s role? (frontend \u002F backend \u002F fullstack \u002F config)\"\n   - Write `role:` to the repo's entry in config.yaml\n   - If `capabilities:` exists on that entry, remove it\n\n### 10c. Preferences\n\nAsk via AskUserQuestion (one at a time):\n1. \"Auto-commit after each plan step? (y\u002Fn, default: n)\"\n2. \"Auto-create PR when all steps complete? (y\u002Fn, default: n)\"\n3. \"Docs repo URL for seed data refresh? (ADO URL or blank)\"\n\n### 10d. Read Defaults\n\nFrom `project.yaml` → `defaults`:\n- `qa-author-url` → write to `aem.author-url-qa`\n- `qa-publish-url` → write to `aem.publish-url-qa` (if present)\n\n### 10e. Write Project Config\n\n**Update top-level `repos:` section** (NOT under `aem:`):\n\nFor each repo, ensure these fields are present:\n```yaml\nrepos:\n  - name: \u003Crepo>\n    path: \u003Crelative-path>\n    role: \u003Crole>                      # preserved from dx-init\n    platform: \u003Cplatform>              # NEW — from project.yaml\n    ado-project: \u003Cproject>            # NEW — from project.yaml (if different from scm.project)\n    base-branch: \u003Cbranch>             # NEW — user input or scm.base-branch default\n```\n\n**Remove `aem.repos` if present** (migrated to top-level `repos:`).\n**Remove `aem.current-repo`** (redundant — current repo is implicit).\n**Keep `aem.platform`** (quick self-identification for the current repo).\n\nAppend\u002Fupdate these fields in the `aem:` section of `.ai\u002Fconfig.yaml`:\n\n```yaml\naem:\n  # ... existing aem-init fields (component-path, etc.) ...\n  platform: \u003Cderived from project.yaml>\n  active-brands: [\u003Cbrands>]\n  active-markets: [\u003Cmarket codes>]\n  author-url-qa: \u003Curl from defaults>\n  publish-url-qa: \u003Curl from defaults>\n  docs-repo: \u003Curl>\n  auto-commit: \u003Cbool>\n  auto-pr: \u003Cbool>\n```\n\n### 10f. Re-run Behavior\n\nIf `aem:` section already has project config (`active-brands`, `active-markets`):\n- Ask: \"Project config already exists. **(A) Keep existing**, **(B) Update**?\"\n- If **A**: Skip 10a-10e, continue to step 11\n- If **B**: Run 10a-10e (overwrites project config, preserves other aem: fields)\n\n**Migration from `aem.repos`:** On re-run, if `.ai\u002Fconfig.yaml` has `aem.repos:` but top-level `repos:` is missing or incomplete, migrate: copy entries from `aem.repos` to top-level `repos:`, mapping `local-path` → `path`. Then remove the `aem.repos` section. Report what was migrated.\n\n## 11. AEM Rule Template Installation\n\nCopy rule templates from the plugin `templates\u002Frules\u002F` directory to `.claude\u002Frules\u002F`:\n\n- `audit.md.template` → `.claude\u002Frules\u002Faudit.md` (remote change audit rules)\n- `qa-basic-auth.md.template` → `.claude\u002Frules\u002Fqa-basic-auth.md` (QA\u002Fstage auth credentials)\n\nFor `qa-basic-auth`: the rule now reads credentials from env vars first (`QA_BASIC_AUTH_USER` etc.), with `.ai\u002Fconfig.yaml` as legacy fallback. If `project.yaml` defines `defaults.qa-basic-auth`, still substitute into the rule template for backward compatibility.\n\n**On re-run:** Compare existing file against template. If identical: skip. If template changed and user hasn't customized: update silently. If user customized: show diff, ask.\n\n### 11a. Check AEM Environment Variable\n\nCheck if `AEM_INSTANCES` is already set in the shell environment:\n\n```bash\necho \"$AEM_INSTANCES\"\n```\n\n1. **If set:** Report: \"AEM_INSTANCES detected in shell environment — AEM MCP will use it.\" Skip items 2–3; still run the note below.\n\n2. **If not set:** Print setup instructions:\n\n   ```\n   AEM MCP requires the AEM_INSTANCES environment variable.\n   Add to your shell profile (~\u002F.bashrc or ~\u002F.zshrc):\n\n     export AEM_INSTANCES=\"local:http:\u002F\u002Flocalhost:4502:admin:admin\"\n\n   Format: name:url:user:pass (comma-separated for multiple instances).\n   Then restart your terminal or run: source ~\u002F.zshrc\n\n   Alternative: add to .claude\u002Fsettings.local.json under \"env\" (Claude Code only, not Copilot CLI).\n   ```\n\n3. **Also update `.claude\u002Fsettings.local.json`** — add the `AEM_INSTANCES` key as a placeholder. Do NOT overwrite existing values:\n\n   a. **If file exists:** Merge `AEM_INSTANCES` into the existing `\"env\"` object.\n\n   b. **If file does not exist:** Create it with both base dx env vars and AEM env vars:\n\n   ```json\n   {\n     \"env\": {\n       \"QA_BASIC_AUTH_USER\": \"\",\n       \"QA_BASIC_AUTH_PASS\": \"\",\n       \"QA_BASIC_AUTH_FALLBACK_USER\": \"\",\n       \"QA_BASIC_AUTH_FALLBACK_PASS\": \"\",\n       \"AXE_API_KEY\": \"\",\n       \"AEM_INSTANCES\": \"local:http:\u002F\u002Flocalhost:4502:admin:admin\"\n     }\n   }\n   ```\n\n   Report: \"Updated `.claude\u002Fsettings.local.json` with AEM_INSTANCES. Preferred: set in shell profile for both Claude Code and Copilot CLI.\"\n\n**Note (runs whether or not `AEM_INSTANCES` is set):** if `aem.author-url-qa` or `aem.author-url` has a hostname ending in `.adobeaemcloud.com` (AEM as a Cloud Service), also mention: Adobe hosts its own MCP server at `https:\u002F\u002Fmcp.adobeaemcloud.com\u002Fadobe\u002Fmcp\u002Faem`. It is Cloud Service only, OAuth with the user's Adobe ID, runs with that user's AEM permissions, and Content\u002FCloud Manager can be read-only. The user may add it next to the bundled server for ad-hoc work. It does **not** replace the bundled `AEM` server: dx-aem skills call that server's tools by name, and the Adobe server needs an interactive sign-in a pipeline cannot do.\n\n## 12. Summary\n\n> **Run component discovery for best results:** The `component-discovery.md` file (generated in Step 6b) provides dialog field semantics, component variants, and page locations to all downstream skills (`\u002Fdx-req`, `\u002Fdx-plan`, `\u002Fdx-step`). Without it, these skills rely on Glob\u002FGrep only and may miss field meanings and brand-specific variants. Re-run `\u002Faem-init` after major dialog changes on QA.\n\n```markdown\n## AEM Initialized\n\n**Component Path:** `\u003Cpath>`\n**Brands:** \u003Clist>\n**Active Markets:** \u003Ccodes>\n**Repos:** \u003Ccount> configured (\u003Ccount> with local paths)\n**Config:** `.ai\u002Fconfig.yaml` (aem section updated)\n\n### Seed Data Status\n| File | Status |\n|------|--------|\n| component-index.md | \u003Cgenerated \u002F exists \u002F skipped> |\n| component-discovery.md | \u003Cgenerated \u002F exists \u002F skipped \u002F QA unreachable> |\n| project.yaml | \u003Cfound \u002F not found> |\n| file-patterns.yaml | \u003Cfound \u002F not found> |\n| content-paths.yaml | \u003Cfound \u002F not found> |\n| architecture.md | \u003Cfound \u002F not found> |\n| features.md | \u003Cfound \u002F not found> |\n| component-index-project.md | \u003Cfound \u002F not found> |\n\n### Next Steps\n- `\u002Faem-component \u003Cname>` — look up a component's files and pages\n- `\u002Faem-refresh` — refresh seed data from docs repo\n- `\u002Faem-snapshot \u003Cname>` — capture baseline before development\n- `\u002Faem-verify \u003Cname>` — verify after deployment\n```\n\n## Examples\n\n1. `\u002Faem-init` — First run after `\u002Fdx-init`. Detects `ui.frontend\u002Fsrc\u002Fcore\u002Fcomponents\u002F` and `ui.frontend\u002Fsrc\u002Fbrand\u002Fcomponents\u002F` directories, identifies brands from the project's component directories, and appends `aem:` section to `.ai\u002Fconfig.yaml` with author URL, publisher URL, component paths, and active markets.\n\n2. `\u002Faem-init` (re-run to update markets) — Detects existing `aem:` section in config. Asks whether to re-detect or update specific values. User updates `active-markets` from `[gb, de]` to `[gb, de, fr]`. Refreshes seed data files in `.ai\u002Fproject\u002F`.\n\n3. `\u002Faem-init` (with component index scan) — After detecting project structure, asks \"Scan AEM for component index?\" User confirms. Queries AEM author instance for all components under `\u002Fapps\u002F`, builds `component-index-project.md` with component names, resource types, and dialog field counts.\n\n## Troubleshooting\n\n- **\"`.ai\u002Fconfig.yaml` not found — run `\u002Fdx-init` first\"**\n  **Cause:** `\u002Faem-init` requires the base config created by `\u002Fdx-init`.\n  **Fix:** Run `\u002Fdx-init` first to create `.ai\u002Fconfig.yaml`, then run `\u002Faem-init` to add the AEM section.\n\n- **Component index scan fails or returns empty**\n  **Cause:** AEM author instance is not running or not reachable at the configured URL.\n  **Fix:** Start AEM locally or verify `aem.author-url` in `.ai\u002Fconfig.yaml`. The component index is optional — skip it and run `\u002Faem-init` again later when AEM is available.\n\n- **Seed data files missing after init**\n  **Cause:** The plugin's `data\u002F` directory doesn't contain seed files for this project, or the copy step was skipped.\n  **Fix:** Run `\u002Faem-refresh` to pull seed data from the docs repo or a local path. Check that `.ai\u002Fproject\u002F` contains `project.yaml`, `file-patterns.yaml`, `content-paths.yaml`, and `architecture.md`.\n\n## Rules\n\n- **Interactive — use AskUserQuestion** — Every question, confirmation, or choice in this skill MUST use the `AskUserQuestion` tool to pause and wait for the user's response. Never proceed past a question without receiving the user's answer first. Present numbered options in the question text, then STOP and wait. Do not batch multiple questions into one message — ask one, wait for the answer, then continue.\n- **dx-init required first** — `.ai\u002Fconfig.yaml` must exist before adding AEM config\n- **Detect first, ask second** — auto-detect everything possible\n- **Append, don't overwrite** — add `aem:` section to existing config\n- **Validate on re-run** — every step executes on re-run; validate existing files against plugin templates, smart-update what's outdated, ask when in doubt\n- **Component index is optional** — ask before scanning (can be slow for large projects)\n- **No hardcoded paths** — detect from the actual project structure\n","You configure AEM-specific settings by detecting the project structure and appending an `aem:` section to `.ai\u002Fconfig.yaml`.\n\n## Re-run Validation Protocol\n\n**CRITICAL: When aem-init is re-run, EVERY step MUST execute. NEVER stop early.** If the user chooses \"Keep as-is\" for config, skip to step 6 and continue through ALL remaining steps (6→7→8→9). Each step validates:\n\n| File Category | Re-run Behavior |\n|---|---|\n| **Config** (aem: section in config.yaml) | Ask: keep \u002F modify \u002F regenerate |\n| **Component index** (.ai\u002Fproject\u002Fcomponent-index.md) | Offer to re-scan if stale |\n| **Component discovery** (.ai\u002Fproject\u002Fcomponent-discovery.md) | Offer to re-scan if stale (AEM dialog changes on QA) |\n| **Shared rule extensions** (pr-review.md, pr-answer.md AEM sections) | Validate sections exist, re-append if missing |\n| **Rule templates** (.claude\u002Frules\u002Fbe-*.md, fe-*.md) | Compare against plugin template → if template changed and user hasn't customized: update. If user customized: show diff, ask |\n| **Copilot instructions** | Copilot CLI v1.0.89+ reads `.claude\u002Frules\u002F` natively — no copies, no env var |\n| **Copilot agents** (.github\u002Fagents\u002FAEM*.md) | Compare against plugin template → update silently if changed |\n\n> **Inline execution from dx-init:** When this skill is run inline from `\u002Fdx-init` step 7 (AEM auto-chain), skip Copilot-related steps: **8a** (Copilot question), **8e** (AEM Copilot agent templates), and **8f** (copilot-instructions.md update). Also skip **step 9** (Confirm). These are handled by dx-init steps 9 and 10 instead. Set `COPILOT_ENABLED=false` as default — dx-init handles Copilot output separately.\n\n## 1. Check Prerequisites\n\nCheck if `.ai\u002Fconfig.yaml` exists. If not: \"Run `\u002Fdx-init` first to set up the base project config.\"\n\nCheck if `.ai\u002Fconfig.yaml` already has an `aem:` section:\n- **If it exists:** Display current AEM config and ask: \"AEM config already exists. **(A) Keep as-is**, **(B) Modify**, or **(C) Regenerate**?\"\n  - If **A**: Say \"Config kept. Validating all AEM files...\" — then **CONTINUE to step 6** to validate component index, rules, and templates. **DO NOT stop or exit.**\n  - If **B\u002FC**: Continue to step 2\n- **If it doesn't exist:** Continue to step 2.\n\n## 2. Detect AEM Structure\n\n### 2a. Find Component Path\n\nSearch for AEM component definitions using Glob (no Bash needed):\n\n```\nGlob: \"**\u002Fjcr_root\u002Fapps\u002F*\u002Fcomponents\u002F*\u002F.content.xml\"\n```\n\nFrom the results, extract:\n- **Component namespace** — e.g., `\u002Fapps\u002Fmyproject\u002Fcomponents\u002Fcontent\u002F`\n- **Component prefix** — e.g., `myproject` from path patterns\n- **Component group** — from `componentGroup` in `.content.xml` files\n\n### 2b. Detect Module Structure\n\nLook for AEM Maven modules:\n\n| Check | Module Type |\n|-------|------------|\n| `*-core\u002Fpom.xml` with `bundle` packaging | Java\u002FOSGi bundle |\n| `*-apps\u002Fpom.xml` with `content-package` | HTL + dialogs |\n| `*-clientlibs*\u002Fpom.xml` or `frontend\u002F` | Frontend build |\n| `*-config*\u002Fpom.xml` | Configuration |\n| `*-all*\u002Fpom.xml` | Deployable container |\n\n### 2c. Detect Frontend Structure\n\nLook for frontend source locations using Glob (no Bash needed):\n\n```\nGlob: \"*\u002Ffrontend\u002F\"\nGlob: \"**\u002Fui.frontend\u002F\"\nGlob: \"**\u002Fclientlib.config.js\"\nGlob: \"**\u002Fclientlibs\u002F**\u002F.content.xml\"\n```\n\n### 2d. Detect Brands (multi-brand)\n\nLook for brand directories using Glob (no Bash needed):\n\n```\nGlob: \"**\u002Fbrands\u002Fclientlibs\u002F*\u002F\"\n```\n\n## 3. Ask AEM URLs\n\nAsk all four URLs. Author = content editing and dialog testing. Publisher = user-facing website rendering. These are always different instances.\n\n```\n**AEM Author URL (local dev)?** Content editing, dialog testing, component configuration. (default: http:\u002F\u002Flocalhost:4502)\n**AEM Publisher URL (local dev)?** User-facing website rendering. (default: http:\u002F\u002Flocalhost:4503)\n**Remote Author URL (QA\u002Fstage)?** For clickable author links in research output. (leave blank to use dev URL)\n**Remote Publisher URL (QA\u002Fstage)?** For user-facing verification on QA environment. (leave blank to use dev URL)\n```\n\n## 4. Confirm\n\nPresent detected values:\n\n```markdown\n## Detected AEM Configuration\n\n| Property | Value |\n|----------|-------|\n| Component Path | `\u002Fapps\u002F\u003Cprefix>\u002Fcomponents\u002Fcontent\u002F` |\n| Component Prefix | `\u003Cprefix>` |\n| Component Group | `\u003Cgroup>` |\n| Resource Type Pattern | `\u003Cprefix>\u002Fcomponents\u002Fcontent\u002F\u003Cname>` |\n| Java Package | `\u003Cpackage>` (if detected) |\n| Frontend Dir | `\u003Cpath>` |\n| Brands | \u003Clist or \"single-brand\"> |\n| AEM Author (Dev) | `http:\u002F\u002Flocalhost:4502` |\n| AEM Publisher (Dev) | `http:\u002F\u002Flocalhost:4503` |\n| AEM Author (QA) | `\u003Curl or \"same as dev\">` |\n| AEM Publisher (QA) | `\u003Curl or \"same as dev\">` |\n\n**Correct?** Type \"yes\" or tell me what to change.\n```\n\n## 5. Append to Config\n\nAppend `aem:` section to `.ai\u002Fconfig.yaml`:\n\n```yaml\naem:\n  component-path: \"\u002Fapps\u002F\u003Cprefix>\u002Fcomponents\u002Fcontent\"\n  component-prefix: \"\u003Cprefix>\"\n  component-group: \"\u003Cgroup>\"\n  resource-type-pattern: \"\u003Cprefix>\u002Fcomponents\u002Fcontent\u002F\u003Cname>\"\n  java-package: \"\u003Cpackage>\"              # if detected\n  frontend-dir: \"\u003Cpath>\"                 # if detected\n  brands: [\u003Clist>]                       # if multi-brand\n  author-url: \"http:\u002F\u002Flocalhost:4502\"    # Author — dialog\u002Fcomponent editing\n  author-url-qa: \"\u003Curl>\"                 # Remote author — clickable links in research output\n  publish-url: \"http:\u002F\u002Flocalhost:4503\"   # Publisher — user-facing website\n  publish-url-qa: \"\u003Curl>\"               # Remote publisher — user-facing verification on QA\n  demo-parent-path: \"\u003Cpath>\"             # Parent for AI-created demo pages (e.g., \u002Fcontent\u002Fmysite\u002Fen\u002Fdemo)\n  # selector: \"\u003Cexporter-selector>\"      # Uncomment if project uses custom selector\n```\n\n## 6. Component Discovery\n\n### 6a. Glob-based Component Index (structural)\n\nAsk: \"Scan for existing components and generate `.ai\u002Fproject\u002Fcomponent-index.md`? This helps `\u002Faem-component` and `\u002Fdx-ticket-analyze` find files faster.\"\n\nIf yes:\n1. Glob for all component `.content.xml` files under the component path\n2. Extract: name, title, group, resource type, resourceSuperType\n3. Write `.ai\u002Fproject\u002Fcomponent-index.md` as a lookup table (create `.ai\u002Fproject\u002F` if needed)\n\n### 6b. AEM MCP Component Discovery (semantic)\n\nAsk: \"Query AEM QA for component dialog fields, variants, and pages? This creates `.ai\u002Fproject\u002Fcomponent-discovery.md` for richer AI planning. Requires AEM QA to be reachable.\"\n\nIf yes:\n\n**Prerequisites check:**\n1. `aem.author-url-qa` must be configured. If not: warn \"Set `aem.author-url-qa` in config to enable component discovery.\" and skip.\n2. Test AEM QA reachability: `mcp__plugin_dx-aem_AEM__getNodeContent` on the component root path. If unreachable: warn \"AEM QA not reachable — component-discovery.md skipped. Run `\u002Faem-init` again when QA is available.\" and skip.\n\n**Discovery logic:**\n\nFor each component found by Step 6a's Glob scan (scoped to this repo's `aem.component-path`):\n\n1. **Dialog fields** — `mcp__plugin_dx-aem_AEM__getNodeContent` on `\u003Ccomponent-path>\u002F\u003Cname>\u002F_cq_dialog` with depth 6. Extract: field name, `sling:resourceType` (maps to field type), `fieldLabel`, `fieldDescription`, `required` flag.\n\n2. **Variants in this repo** — Glob sibling directories with same name suffix under the component path. E.g., if component is `productcard`, check for `*-productcard` or `productcard-*` siblings.\n\n3. **Variants in other repos** — `mcp__plugin_dx-aem_AEM__searchContent` for components whose `sling:resourceSuperType` equals this component's resourceType. Cross-reference with `repos:` section in config.yaml to note owning repo.\n\n4. **Pages using component** — `mcp__plugin_dx-aem_AEM__searchContent` by `sling:resourceType` under the content roots from `content-paths.yaml` or `aem.demo-parent-path` parent. Limit to 5 pages.\n\n5. **Authored values** — For the first page found, `mcp__plugin_dx-aem_AEM__getNodeContent` on the component instance (depth 4). Extract actual field values to reveal semantic meaning.\n\n**Parallelism:** Dispatch one Explore agent per ~10 components. Each agent receives the component list, AEM QA URL, and query instructions. Agents use `mcp__plugin_dx-aem_AEM__*` tools directly.\n\n**Output:** Write `.ai\u002Fproject\u002Fcomponent-discovery.md` with format:\n\n```markdown\n# AEM Component Discovery\n\n**Generated:** \u003Cdate>\n**Instance:** \u003Caem.author-url-qa> (QA)\n**Repo:** \u003Cscm.repo or project name>\n**Scope:** \u003Caem.resource-type-pattern>* (\u003Ccount> components)\n\n## \u003Ccomponent-name>\n\n**Resource Type:** \u003Cfull resource type>\n**Owner:** \u003Crepo name> (this repo)\n**Variants (this repo):** \u003Ccomma-separated list or \"none\">\n**Variants (other repos):**\n  - `\u003Cvariant-name>` → \u003Crepo-name> (superType: \u003Cthis component's resourceType>)\n\n### Dialog Fields\n| Field | Type | Label | Description | Required |\n|-------|------|-------|-------------|----------|\n| \u003Cname> | \u003Ctype> | \u003CfieldLabel> | \u003CfieldDescription> | \u003Cyes\u002Fno> |\n\n### Sample Authored Values (from \u003Cpage-path>)\n| Field | Value |\n|-------|-------|\n| \u003Cname> | \u003Cvalue or \"(empty)\"> |\n\n### Pages (\u003Ccount>)\n- \u003Cpage-path-1>\n- \u003Cpage-path-2>\n...\n\n### Cross-Repo Dependencies\n- **superType:** \u003CsuperType resource type> → \u003Crepo name> (base)\n```\n\nFor brand-override repos: dialog fields note `inherited from \u003Cbase>` vs `LOCAL (this repo)`.\n\n**Re-run behavior:** If `.ai\u002Fproject\u002Fcomponent-discovery.md` already exists, ask \"Re-scan component discovery? (recommended after dialog changes on QA)\". If no: keep existing, report \"validated (kept existing)\".\n\n## 7. Extend Shared Rules with AEM Patterns\n\nAppend AEM-specific focus areas to the shared rules in `.ai\u002Frules\u002F` (installed by dx-init). This ensures both local dx skills and automation agents apply AEM review criteria.\n\n**Idempotent:** check if the section already exists before appending.\n\n### 7a. Extend pr-review.md\n\nIf `.ai\u002Frules\u002Fpr-review.md` exists:\n\n1. Read the file and check if it contains `## AEM\u002FSling Patterns` (use Grep tool, not Bash)\n2. If NOT found, append:\n\n```markdown\n\n## AEM\u002FSling Patterns\n- Verify Sling Model annotations: correct adaptables, resource types, injection strategies\n- Check @Self @Via(ResourceSuperType) delegation patterns\n- Validate OSGi service references use proper injection\n- Ensure ResourceResolver lifecycle is respected (no leaked resolvers)\n\n## Frontend Patterns\n- Check component-loader registration matches class name\n- Verify config files externalize DOM selectors and CSS classes\n- Check PubSub event usage matches constants from commons\u002Fconstants\u002Fevents.js\n- Validate SCSS uses @use\u002F@forward (not @import)\n```\n\n### 7b. Extend pr-answer.md\n\nIf `.ai\u002Frules\u002Fpr-answer.md` exists:\n\n1. Read the file and check if it contains `## AEM\u002FSling Patterns` (use Grep tool, not Bash)\n2. If NOT found, append:\n\n```markdown\n\n## AEM\u002FSling Patterns\n- Understand @Self @Via(ResourceSuperType) delegation\n- Understand Sling Model injection strategies\n- Know when OSGi service patterns are intentional\n\n## Frontend Patterns\n- Understand component-loader registration\n- Know config externalization patterns\n- Understand PubSub event communication\n- SCSS uses @use\u002F@forward (not @import)\n```\n\nIf `.ai\u002Frules\u002Fpr-review.md` or `.ai\u002Frules\u002Fpr-answer.md` does not exist, skip and note: \"Shared rules not found — run `\u002Fdx-init` first.\"\n\n## 8. Copy Convention Templates\n\nUnified convention templates (`templates\u002Frules\u002F`) contain dual frontmatter (`paths:` for Claude Code, `applyTo:` for Copilot CLI). Each template is copied to `.claude\u002Frules\u002F`. Copilot CLI v1.0.89+ reads rules from this same location natively and maps `paths:` to its scope — no `.github\u002Finstructions\u002F` copies, no env var.\n\n### 8a. Ask about Copilot support\n\n```\n**Support GitHub Copilot CLI?** (default: yes)\nIf yes:\n- AEM Copilot agent definitions are generated in `.github\u002Fagents\u002F`\nIf no:\n- No Copilot agents generated\n```\n\nSet `COPILOT_ENABLED=true` or `COPILOT_ENABLED=false` based on the answer.\n\n### 8b. Create target directories\n\nEnsure `.claude\u002Frules\u002F` exists. The Write tool creates parent directories automatically, so no explicit mkdir is needed.\n\n### 8c. Copy rule templates to `.claude\u002Frules\u002F`\n\n1. Read `project.role` from `.ai\u002Fconfig.yaml`\n2. Determine which template directories to install:\n\n| `project.role` | Directories |\n|---|---|\n| `frontend` | `shared\u002F` + `fe\u002F` |\n| `backend` | `shared\u002F` + `be\u002F` |\n| `fullstack` | `shared\u002F` + `be\u002F` + `fe\u002F` |\n| `config` | `shared\u002F` only |\n| (not set) | All directories (backward compatibility) |\n\n3. For each selected directory, Glob template files (no Bash needed):\n```\nGlob: \"\u003Cplugin-path>\u002Ftemplates\u002Frules\u002F\u003Cdir>\u002F*.md.template\"\n```\n\n4. For each template file found:\n\nDerive target filename by stripping the `.template` suffix (e.g., `be-sling-models.md.template` → `be-sling-models.md`).\n\n**If `.claude\u002Frules\u002F\u003Ctarget>` already exists:**\nRead both the existing file and the plugin template. Compare content:\n- **Identical:** Report \"validated (up to date)\", skip.\n- **Template changed, file matches old template:** Update silently — the user hasn't customized it.\n- **User has customized (content differs from template):** Show the diff summary and ask: **(A) Keep existing**, **(B) Replace with updated template**, **(C) Write updated as `.template`** (user can diff manually).\n\n**Check for topic overlap (new files only):**\nScan existing `.claude\u002Frules\u002F*.md` — read their frontmatter (`description` and `paths` fields). Compare against the template's `paths` glob and topic (filename prefix: `fe-` or `be-`). If a file with overlapping paths and similar topic exists:\n\n- Show both filenames and their descriptions side-by-side\n- Ask: **(A) Skip** (keep existing), **(B) Replace** (overwrite with template), **(C) Write as `.template`** (user can diff manually)\n\n**No conflict:**\nCopy the file to `.claude\u002Frules\u002F\u003Ctarget>`, stripping the `.template` extension.\n\n5. Resolve template variables before writing:\n\nRead from `.ai\u002Fconfig.yaml`:\n\n| Variable | Config source |\n|---|---|\n| `{{COMPONENT_PREFIX}}` | `aem.component-prefix` |\n| `{{DAM_PATH}}` | `aem.dam-path` |\n| `{{CSS_PREFIX}}` | `aem.component-prefix` (fallback: `project.prefix`) |\n| `{{BUILD_TOOL}}` | `toolchain.build-tool` |\n| `{{CSS_COMPILER}}` | `toolchain.css-compiler` |\n| `{{NODE_VERSION}}` | `toolchain.node` |\n| `{{COMPONENT_BASE_CLASS}}` | `toolchain.component-base-class` |\n| `{{RESOURCE_TYPE_PATTERN}}` | `aem.resource-type-pattern` |\n\nFor each variable, if the config value is empty or missing, leave the placeholder as-is (consumer will fill in or the value is not relevant for this project).\n\n> **Note:** `.github\u002Finstructions\u002F` copies are no longer generated. Copilot CLI v1.0.89+ reads rules directly from `.claude\u002Frules\u002F`. Rules with dual frontmatter (`paths:` + `applyTo:`) work in both tools from a single source.\n\n### 8d. (Removed — instruction templates merged into rule templates)\n\nInstruction templates no longer exist as separate files. The unified rule templates in `templates\u002Frules\u002F` contain both `paths:` (Claude Code) and `applyTo:` (Copilot CLI) frontmatter. Step 8c handles both outputs.\n\n### 8e. Copy AEM Copilot agent templates (if Copilot enabled)\n\nOnly if the user answered \"yes\" to Copilot support in step 7a.\n\nUse Glob to find agent template files (no Bash needed):\n```\nGlob: \"\u003Cplugin-path>\u002Ftemplates\u002Fagents\u002F*.agent.md.template\"\n```\n\nFor each result:\n\n1. Read the template\n2. Strip the `.template` suffix from the filename\n3. Write to `.github\u002Fagents\u002F\u003CAgentName>.agent.md`\n\n**On re-run:** If `.github\u002Fagents\u002F\u003Ctarget>` already exists, compare against the plugin template. Update silently if the template has changed (Copilot agents are not user-customized). Report \"validated\" or \"updated\".\n\n### 8f. Update copilot-instructions.md (if Copilot enabled and file exists)\n\nIf `.github\u002Fcopilot-instructions.md` exists (generated by `\u002Fdx-init`), append an AEM agents section:\n\n```markdown\n\n## AEM Agents\n\n| Agent | Purpose | Invoke |\n|-------|---------|--------|\n| AEMBefore | Pre-development baseline snapshot | `@AEMBefore \u003Ccomponent>` |\n| AEMAfter | Post-deployment verification | `@AEMAfter \u003Ccomponent>` |\n| AEMSnapshot | Component inspection | `@AEMSnapshot \u003Ccomponent>` |\n| AEMDemo | Dialog screenshot + authoring guide | `@AEMDemo \u003Ccomponent>` |\n| AEMComponent | Find pages using a component | `@AEMComponent \u003Ccomponent>` |\n| AEMVerify | Bug verification on AEM | `@AEMVerify \u003Ccomponent>` |\n```\n\nIf the file doesn't exist, skip this step (it means `\u002Fdx-init` didn't generate Copilot files).\n\n### 8g. Install AEM browser-auth helper (Playwright)\n\nCopy the reusable auth helper so browser agents can authenticate to AEM without the password ever entering the model's context.\n\n1. Copy `..\u002F..\u002Fdata\u002Flib\u002Faem-playwright-auth.sh` (relative to this skill's directory — the dx-aem plugin's `data\u002Flib\u002F`) → `.ai\u002Flib\u002Faem-playwright-auth.sh` (create `.ai\u002Flib\u002F` if missing; `chmod +x`). On re-run, overwrite silently if the plugin version changed.\n2. Ensure the consumer `.gitignore` contains `.ai\u002Fplaywright\u002F` (the helper writes the session cookie + Basic Auth creds there — must never be committed). Append it under the runtime-output block if absent.\n3. **Install the Playwright browser** (one-time): the dx-aem `playwright` MCP server drives a real Chromium that is NOT bundled — without it, every browser skill (`\u002Faem-verify`, `\u002Faem-qa`, `\u002Faem-fe-verify`, `\u002Faem-editorial-guide`) fails at first navigation. Run:\n   ```bash\n   npx playwright install chromium\n   ```\n   It's idempotent (no-op if already present). If it fails (offline\u002Frestricted), tell the user to run it manually before any browser verification.\n\n**What it provides** (two independent auth layers — see the `qa-basic-auth` rule):\n- **AEM author login** → `bash .ai\u002Flib\u002Faem-playwright-auth.sh author \u003Clocal|qa>` writes `.ai\u002Fplaywright\u002Faem-author-state.json` (a Playwright `storageState` with the `login-token` cookie). Browser agents load it via `browser_set_storage_state` before navigating to the author — no form-fill, no password in context.\n- **Publisher Basic Auth** (opt-in) → `bash .ai\u002Flib\u002Faem-playwright-auth.sh config` writes `.ai\u002Fplaywright\u002Fconfig.json` with `httpCredentials` from `QA_BASIC_AUTH_*`. To use it browser-natively, add `\"--config\", \".ai\u002Fplaywright\u002Fconfig.json\"` to the `playwright` server args in `.mcp.json`. (Default skills use URL-embedded Basic Auth, which needs no config.)\n\n### 8h. Report results\n\n```markdown\n### Convention Files\n\n**Rules** (`.claude\u002Frules\u002F`): \u003CN> written, \u003CN> skipped\n\u003CIf Copilot enabled:>\n**Copilot instructions**: Copilot CLI v1.0.89+ reads `.claude\u002Frules\u002F` natively (no copies needed)\n**Copilot Agents** (`.github\u002Fagents\u002F`): \u003CN> written, \u003CN> skipped\n```\n\n## 9. Confirm\n\n```markdown\n## AEM Initialized\n\n**Component Path:** `\u003Cpath>`\n**Brands:** \u003Clist>\n**Config:** `.ai\u002Fconfig.yaml` (aem section appended)\n\n### Next Steps\n- `\u002Faem-component \u003Cname>` — look up a component's files and pages\n- `\u002Faem-snapshot \u003Cname>` — capture baseline before development\n- `\u002Faem-verify \u003Cname>` — verify after deployment\n```\n\n## 10. Project Setup (if seed data exists)\n\nCheck if `.ai\u002Fproject\u002Fproject.yaml` exists. If not, print: \"No project.yaml found. To add project knowledge, create `.ai\u002Fproject\u002Fproject.yaml`. See docs\u002Fauthoring\u002Fseed-data-guide.md for format.\" Then skip to step 11.\n\nIf project.yaml exists:\n\n### 10a. Brand\u002FMarket Selection\n\n1. Read `project.yaml` → `brands[]` list\n2. For each brand:\n   - If `single-market: true`: auto-confirm this brand and its single market. Report \"Auto-confirmed: \u003Cbrand> (\u003Cmarket>)\"\n   - Otherwise: Ask via AskUserQuestion: \"Which markets are active for **\u003Cbrand>**? Options: \u003Cmarket codes>. Enter comma-separated codes or 'all'.\"\n3. Store selected brands and market codes\n\n### 10b. Repo Local Paths\n\n1. Read existing `repos:` from `.ai\u002Fconfig.yaml` (written by `\u002Fdx-init`)\n2. Read `repos[]` from `.ai\u002Fproject\u002Fproject.yaml` for platform and ado-project data\n3. For each repo in project.yaml NOT already in config `repos:`, add it with `name` and `path` (ask: \"Local path for **\u003Crepo>**? (default: `..\u002F\u003Cname>`)\")\n4. For each repo in config `repos:`, enrich with fields from project.yaml: `platform`, `ado-project`\n5. If `path` is missing on any entry, ask: \"Local path for **\u003Crepo>**? (default: `..\u002F\u003Cname>`)\"\n6. Ask for `base-branch` if not set (default: same as `scm.base-branch`)\n7. For each repo in `repos:`, if `role:` is missing or `capabilities:` is present:\n   - Ask via AskUserQuestion: \"What is **\u003Crepo>**'s role? (frontend \u002F backend \u002F fullstack \u002F config)\"\n   - Write `role:` to the repo's entry in config.yaml\n   - If `capabilities:` exists on that entry, remove it\n\n### 10c. Preferences\n\nAsk via AskUserQuestion (one at a time):\n1. \"Auto-commit after each plan step? (y\u002Fn, default: n)\"\n2. \"Auto-create PR when all steps complete? (y\u002Fn, default: n)\"\n3. \"Docs repo URL for seed data refresh? (ADO URL or blank)\"\n\n### 10d. Read Defaults\n\nFrom `project.yaml` → `defaults`:\n- `qa-author-url` → write to `aem.author-url-qa`\n- `qa-publish-url` → write to `aem.publish-url-qa` (if present)\n\n### 10e. Write Project Config\n\n**Update top-level `repos:` section** (NOT under `aem:`):\n\nFor each repo, ensure these fields are present:\n```yaml\nrepos:\n  - name: \u003Crepo>\n    path: \u003Crelative-path>\n    role: \u003Crole>                      # preserved from dx-init\n    platform: \u003Cplatform>              # NEW — from project.yaml\n    ado-project: \u003Cproject>            # NEW — from project.yaml (if different from scm.project)\n    base-branch: \u003Cbranch>             # NEW — user input or scm.base-branch default\n```\n\n**Remove `aem.repos` if present** (migrated to top-level `repos:`).\n**Remove `aem.current-repo`** (redundant — current repo is implicit).\n**Keep `aem.platform`** (quick self-identification for the current repo).\n\nAppend\u002Fupdate these fields in the `aem:` section of `.ai\u002Fconfig.yaml`:\n\n```yaml\naem:\n  # ... existing aem-init fields (component-path, etc.) ...\n  platform: \u003Cderived from project.yaml>\n  active-brands: [\u003Cbrands>]\n  active-markets: [\u003Cmarket codes>]\n  author-url-qa: \u003Curl from defaults>\n  publish-url-qa: \u003Curl from defaults>\n  docs-repo: \u003Curl>\n  auto-commit: \u003Cbool>\n  auto-pr: \u003Cbool>\n```\n\n### 10f. Re-run Behavior\n\nIf `aem:` section already has project config (`active-brands`, `active-markets`):\n- Ask: \"Project config already exists. **(A) Keep existing**, **(B) Update**?\"\n- If **A**: Skip 10a-10e, continue to step 11\n- If **B**: Run 10a-10e (overwrites project config, preserves other aem: fields)\n\n**Migration from `aem.repos`:** On re-run, if `.ai\u002Fconfig.yaml` has `aem.repos:` but top-level `repos:` is missing or incomplete, migrate: copy entries from `aem.repos` to top-level `repos:`, mapping `local-path` → `path`. Then remove the `aem.repos` section. Report what was migrated.\n\n## 11. AEM Rule Template Installation\n\nCopy rule templates from the plugin `templates\u002Frules\u002F` directory to `.claude\u002Frules\u002F`:\n\n- `audit.md.template` → `.claude\u002Frules\u002Faudit.md` (remote change audit rules)\n- `qa-basic-auth.md.template` → `.claude\u002Frules\u002Fqa-basic-auth.md` (QA\u002Fstage auth credentials)\n\nFor `qa-basic-auth`: the rule now reads credentials from env vars first (`QA_BASIC_AUTH_USER` etc.), with `.ai\u002Fconfig.yaml` as legacy fallback. If `project.yaml` defines `defaults.qa-basic-auth`, still substitute into the rule template for backward compatibility.\n\n**On re-run:** Compare existing file against template. If identical: skip. If template changed and user hasn't customized: update silently. If user customized: show diff, ask.\n\n### 11a. Check AEM Environment Variable\n\nCheck if `AEM_INSTANCES` is already set in the shell environment:\n\n```bash\necho \"$AEM_INSTANCES\"\n```\n\n1. **If set:** Report: \"AEM_INSTANCES detected in shell environment — AEM MCP will use it.\" Skip items 2–3; still run the note below.\n\n2. **If not set:** Print setup instructions:\n\n   ```\n   AEM MCP requires the AEM_INSTANCES environment variable.\n   Add to your shell profile (~\u002F.bashrc or ~\u002F.zshrc):\n\n     export AEM_INSTANCES=\"local:http:\u002F\u002Flocalhost:4502:admin:admin\"\n\n   Format: name:url:user:pass (comma-separated for multiple instances).\n   Then restart your terminal or run: source ~\u002F.zshrc\n\n   Alternative: add to .claude\u002Fsettings.local.json under \"env\" (Claude Code only, not Copilot CLI).\n   ```\n\n3. **Also update `.claude\u002Fsettings.local.json`** — add the `AEM_INSTANCES` key as a placeholder. Do NOT overwrite existing values:\n\n   a. **If file exists:** Merge `AEM_INSTANCES` into the existing `\"env\"` object.\n\n   b. **If file does not exist:** Create it with both base dx env vars and AEM env vars:\n\n   ```json\n   {\n     \"env\": {\n       \"QA_BASIC_AUTH_USER\": \"\",\n       \"QA_BASIC_AUTH_PASS\": \"\",\n       \"QA_BASIC_AUTH_FALLBACK_USER\": \"\",\n       \"QA_BASIC_AUTH_FALLBACK_PASS\": \"\",\n       \"AXE_API_KEY\": \"\",\n       \"AEM_INSTANCES\": \"local:http:\u002F\u002Flocalhost:4502:admin:admin\"\n     }\n   }\n   ```\n\n   Report: \"Updated `.claude\u002Fsettings.local.json` with AEM_INSTANCES. Preferred: set in shell profile for both Claude Code and Copilot CLI.\"\n\n**Note (runs whether or not `AEM_INSTANCES` is set):** if `aem.author-url-qa` or `aem.author-url` has a hostname ending in `.adobeaemcloud.com` (AEM as a Cloud Service), also mention: Adobe hosts its own MCP server at `https:\u002F\u002Fmcp.adobeaemcloud.com\u002Fadobe\u002Fmcp\u002Faem`. It is Cloud Service only, OAuth with the user's Adobe ID, runs with that user's AEM permissions, and Content\u002FCloud Manager can be read-only. The user may add it next to the bundled server for ad-hoc work. It does **not** replace the bundled `AEM` server: dx-aem skills call that server's tools by name, and the Adobe server needs an interactive sign-in a pipeline cannot do.\n\n## 12. Summary\n\n> **Run component discovery for best results:** The `component-discovery.md` file (generated in Step 6b) provides dialog field semantics, component variants, and page locations to all downstream skills (`\u002Fdx-req`, `\u002Fdx-plan`, `\u002Fdx-step`). Without it, these skills rely on Glob\u002FGrep only and may miss field meanings and brand-specific variants. Re-run `\u002Faem-init` after major dialog changes on QA.\n\n```markdown\n## AEM Initialized\n\n**Component Path:** `\u003Cpath>`\n**Brands:** \u003Clist>\n**Active Markets:** \u003Ccodes>\n**Repos:** \u003Ccount> configured (\u003Ccount> with local paths)\n**Config:** `.ai\u002Fconfig.yaml` (aem section updated)\n\n### Seed Data Status\n| File | Status |\n|------|--------|\n| component-index.md | \u003Cgenerated \u002F exists \u002F skipped> |\n| component-discovery.md | \u003Cgenerated \u002F exists \u002F skipped \u002F QA unreachable> |\n| project.yaml | \u003Cfound \u002F not found> |\n| file-patterns.yaml | \u003Cfound \u002F not found> |\n| content-paths.yaml | \u003Cfound \u002F not found> |\n| architecture.md | \u003Cfound \u002F not found> |\n| features.md | \u003Cfound \u002F not found> |\n| component-index-project.md | \u003Cfound \u002F not found> |\n\n### Next Steps\n- `\u002Faem-component \u003Cname>` — look up a component's files and pages\n- `\u002Faem-refresh` — refresh seed data from docs repo\n- `\u002Faem-snapshot \u003Cname>` — capture baseline before development\n- `\u002Faem-verify \u003Cname>` — verify after deployment\n```\n\n## Examples\n\n1. `\u002Faem-init` — First run after `\u002Fdx-init`. Detects `ui.frontend\u002Fsrc\u002Fcore\u002Fcomponents\u002F` and `ui.frontend\u002Fsrc\u002Fbrand\u002Fcomponents\u002F` directories, identifies brands from the project's component directories, and appends `aem:` section to `.ai\u002Fconfig.yaml` with author URL, publisher URL, component paths, and active markets.\n\n2. `\u002Faem-init` (re-run to update markets) — Detects existing `aem:` section in config. Asks whether to re-detect or update specific values. User updates `active-markets` from `[gb, de]` to `[gb, de, fr]`. Refreshes seed data files in `.ai\u002Fproject\u002F`.\n\n3. `\u002Faem-init` (with component index scan) — After detecting project structure, asks \"Scan AEM for component index?\" User confirms. Queries AEM author instance for all components under `\u002Fapps\u002F`, builds `component-index-project.md` with component names, resource types, and dialog field counts.\n\n## Troubleshooting\n\n- **\"`.ai\u002Fconfig.yaml` not found — run `\u002Fdx-init` first\"**\n  **Cause:** `\u002Faem-init` requires the base config created by `\u002Fdx-init`.\n  **Fix:** Run `\u002Fdx-init` first to create `.ai\u002Fconfig.yaml`, then run `\u002Faem-init` to add the AEM section.\n\n- **Component index scan fails or returns empty**\n  **Cause:** AEM author instance is not running or not reachable at the configured URL.\n  **Fix:** Start AEM locally or verify `aem.author-url` in `.ai\u002Fconfig.yaml`. The component index is optional — skip it and run `\u002Faem-init` again later when AEM is available.\n\n- **Seed data files missing after init**\n  **Cause:** The plugin's `data\u002F` directory doesn't contain seed files for this project, or the copy step was skipped.\n  **Fix:** Run `\u002Faem-refresh` to pull seed data from the docs repo or a local path. Check that `.ai\u002Fproject\u002F` contains `project.yaml`, `file-patterns.yaml`, `content-paths.yaml`, and `architecture.md`.\n\n## Rules\n\n- **Interactive — use AskUserQuestion** — Every question, confirmation, or choice in this skill MUST use the `AskUserQuestion` tool to pause and wait for the user's response. Never proceed past a question without receiving the user's answer first. Present numbered options in the question text, then STOP and wait. Do not batch multiple questions into one message — ask one, wait for the answer, then continue.\n- **dx-init required first** — `.ai\u002Fconfig.yaml` must exist before adding AEM config\n- **Detect first, ask second** — auto-detect everything possible\n- **Append, don't overwrite** — add `aem:` section to existing config\n- **Validate on re-run** — every step executes on re-run; validate existing files against plugin templates, smart-update what's outdated, ask when in doubt\n- **Component index is optional** — ask before scanning (can be slow for large projects)\n- **No hardcoded paths** — detect from the actual project structure\n",{"name":5,"description":7,"allowed-tools":52,"argument-hint":56},[38,35,45,37,53,54,55],"agent","AEM\u002F*","playwright\u002F*","(no arguments — interactive)","main","5c642842a92100dc7561ae0682a152a74846e186","plugins\u002Fdx-aem\u002Fskills\u002Faem-init",3,"https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow","https:\u002F\u002Fgithub.com\u002Feasingthemes","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fdraganfilipovic\u002F","Agentic SDLC platform in production. I build agent-ready codebases. AEM MCP Server author.","2026-11-11 09:59:48",{"source":8,"skillName":5,"commands":67,"prompt":77,"zipAvailable":78},[68,71,74],{"tool":69,"command":70},"npx","npx skills add easingthemes\u002Fdx-aem-flow --skill aem-init",{"tool":72,"command":73},"bunx","bunx skills add easingthemes\u002Fdx-aem-flow --skill aem-init",{"tool":75,"command":76},"pnpm","pnpm dlx skills add easingthemes\u002Fdx-aem-flow --skill aem-init","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-aem\u002Fskills\u002Faem-init\u002FSKILL.md",true,[],[81,103,122,142,156,171],{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":47},"01M6H48W19F46A7B7TSSQAMYRW","dx-hub-status","Show hub dispatch status — which repos are running, done, blocked or failed. Use for 'hub status', 'what's running'.","https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-hub\u002Fskills\u002Fdx-hub-status\u002FSKILL.md",[],[32,88,89,90,91,92,93,33,94,95,96,97,98,99,100,38,37,101,102],"dx hub status","hub","status","hub status","which","show","ticket","clean","use","done","Bash","id","dispatch","repos","grep",{"skillNo":104,"name":105,"nameZh":6,"description":106,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":107,"categories":108,"keywords":109,"publishedAt":47},"01M6H48R6ZH7YMVPMVWMMWT3RA","dx-hub-init","Initialize a hub directory for multi-repo orchestration. Discovers sibling repos, merges configs, validates CLI compatibility. Use when setting up hub mode for the first time. Trigger on \"init hub\", \"set up hub\", \"multi-repo setup\".","https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-hub\u002Fskills\u002Fdx-hub-init\u002FSKILL.md",[],[28,110,32,111,89,112,113,114,115,116,117,118,44,119,98,120,121,38,37,35],"hub init","dx hub init","SET","time","mode","default","up","repo setup","orchestration","multi-repo","cli","directory",{"skillNo":123,"name":124,"nameZh":6,"description":125,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":126,"categories":127,"keywords":129,"publishedAt":47},"01M6H48K267CWEF8YNN3Y49BVT","dx-hub-dispatch","Dispatch a ticket to several repos — open an independent Claude session per repo in VS Code terminals. Use for 'hub dispatch', 'work on ticket across repos'.","https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-hub\u002Fskills\u002Fdx-hub-dispatch\u002FSKILL.md",[128],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[32,130,100,89,131,33,132,133,134,94,135,136,96,137,98,138,139,140,99,141],"dx hub dispatch","ado","repo","work on","session","open","MCP","URL","vscode","code","across","work",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":148,"publishedAt":47},"01M6H48FAWKTT6AAWT3H80ZKE0","dx-hub-config","View and edit hub configuration — add repos, adjust terminal delay. Use to manage hub settings. Trigger on \"hub config\", \"add repo to hub\", \"terminal delay\".","https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-hub\u002Fskills\u002Fdx-hub-config\u002FSKILL.md",[],[32,149,89,36,93,150,132,151,152,153,154,96,44,98,155,38,29,37,35,101],"dx hub config","view","manage","trigger","true","adjust","terminal",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":162,"publishedAt":47},"01M6H48BNMYEJY6CCWPYHNQDAT","dx-discover-repos","Resolve which repos a work item touches (explicit directive → simple block → cross-repo table → LLM). Used by the KAI-HUB router to fan an agent out across repos; 'which repos'.","https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-hub\u002Fskills\u002Fdx-discover-repos\u002FSKILL.md",[],[163,32,164,101,92,132,140,165,99,166,141,167,89,168,169,170],"discover","dx discover repos","router","directive","simple","block","sonnet","table",{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":175,"categories":176,"keywords":178,"publishedAt":47},"01M6H487QA1FDSBT1HTZGW4HAQ","dx-upgrade","Upgrade a consumer project to the installed plugin versions — run dx-doctor, fix stale and missing files, list manual actions. Use after upgrading plugins.","https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-core\u002Fskills\u002Fdx-upgrade\u002FSKILL.md",[177],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[179,32,180,46,181,45,182,183,184,39,38,37,35,185,186,187,188,96,189,190],"upgrade","dx upgrade","actions","fix","files","auto","list","doctor","manual","missing","plugin","plugins"]