[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6H487QA1FDSBT1HTZGW4HAQ":3,"skill-same:01M6H487QA1FDSBT1HTZGW4HAQ":75},{"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":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":6,"ownerHtmlUrl":57,"ownerBlogUrl":58,"ownerDescription":59,"updatedAt":60,"install":61,"resources":74},"01M6H487QA1FDSBT1HTZGW4HAQ","dx-upgrade",null,"Upgrade a consumer project to the installed plugin versions — run dx-doctor, fix stale and missing files, list manual actions. Use after upgrading plugins.","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-core\u002Fskills\u002Fdx-upgrade\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"dx","dx upgrade","upgrade","plugins","plugin","use","missing","manual","doctor","list","edit","write","read","run","auto","files","fix","search","actions","project","2026-11-10 10:12:30",false,"---\nname: dx-upgrade\ndescription: \"Upgrade a consumer project to the installed plugin versions — run dx-doctor, fix stale and missing files, list manual actions. Use after upgrading plugins.\"\nargument-hint: \"[dx|aem|auto|all]\"\nallowed-tools: [\"read\", \"edit\", \"search\", \"write\", \"agent\"]\n---\n\nYou upgrade a consumer project's dx workflow files to match the latest installed plugin versions. You diagnose first (dx-doctor), then fix issues with smart handling of user-customized files.\n\n## Tool Usage Rules\n\n- **File existence:** Use `Glob` — never `[ -f ]`, `test -f`, or Bash test commands\n- **File content reads:** Use `Read` — never `cat` or `head` in Bash\n- **File writes:** Use `Write` — never `echo >` or `cat \u003C\u003CEOF` in Bash\n- **Content comparison:** Read both files with `Read`, compare in-context — never shell `diff`\n- **Bash is ONLY for:** `chmod +x` on scripts, `bash` to run install\u002Frepair scripts (steps 3e, 3e-ii), and `git` commands\n- **Parallel operations:** Call multiple `Read`\u002F`Write`\u002F`Glob` tools in parallel when independent — do not serialize into one Bash command with `&&`\u002F`||`\n\n## 0. Run dx-doctor\n\nRun the full `\u002Fdx-doctor` flow inline with the same scope argument the user passed. Collect all issues into three categories:\n\n| Category | Description | Examples |\n|----------|-------------|---------|\n| **Auto-fix** | Plugin-owned files that can be updated without asking | Stale utility scripts, stale seed data, stale universal rules, missing template-generated files |\n| **Needs confirmation** | Files the user may have intentionally customized | Stale shared rules (`.ai\u002Frules\u002F*`), stale AEM convention rules, **automation bundle files with functional local divergence** (`.ai\u002Fautomation\u002F**` pipeline YAMLs, lambda handlers, scripts — consumers often prototype steps\u002Fgates\u002Fbranch-pins ahead of the plugin) |\n| **Manual action** | Issues that cannot be auto-fixed | Missing gitignore entries, missing config sections, broken branch references |\n\nIf dx-doctor reports zero issues:\n```\n✓ All checks passed. Nothing to upgrade.\n```\nSTOP.\n\n## 1. Present Fix Plan\n\nBefore applying any fixes, present a summary table for each category:\n\n```markdown\n## Upgrade Plan\n\n### Auto-fix (no confirmation needed)\n| File | Issue | Fix |\n|------|-------|-----|\n| .ai\u002Flib\u002Faudit.sh | stale | Update from plugin |\n| .ai\u002Fproject\u002Fcomponent-index.md | stale | Update from plugin data |\n| .github\u002Fagents\u002F | 4 new, 2 stale | Install new + update stale from templates |\n| .github\u002Fhooks\u002Fhooks.json | 3 dx entries need a plugin root | Repair with repo-hooks-audit.sh --fix |\n\n### Needs confirmation\n| File | Issue | Action |\n|------|-------|--------|\n| .ai\u002Frules\u002Fpr-answer.md | stale | Show diff, ask |\n| .claude\u002Frules\u002Fbe-components.md | stale | Show diff, ask |\n\n### Manual action required\n| Issue | Suggested Fix |\n|-------|--------------|\n| .ai\u002Frun-context\u002F not in .gitignore | Add to .gitignore manually |\n| Missing project seed data | Run \u002Faem-init or \u002Faem-refresh |\n```\n\nAsk: **Proceed with auto-fixes?** (the confirmation items will be handled one-by-one next)\n\nIf the user declines, STOP.\n\n## 1b. Migrate project.yaml (if exists)\n\nIf `.ai\u002Fproject.yaml` exists (NOT `.ai\u002Fproject\u002Fproject.yaml`):\n\n1. Read `.ai\u002Fproject.yaml`\n2. Read `.ai\u002Fconfig.yaml`\n3. Merge fields per mapping:\n   - `type` → `project.type` (add to project: section)\n   - `role` → `project.role` (derive from type if not set: aem-frontend→frontend, aem-fullstack→fullstack, java→backend)\n   - `toolchain.*` → `toolchain:` section (add new top-level section)\n   - `build.serve` → `build.serve` (add if not present)\n   - `build.lint-js` → `build.lint-js` (add if not present)\n   - `build.lint-scss` → `build.lint-scss` (add if not present)\n   - `build.lint-fix` → `build.lint-fix` (add if not present)\n   - `component.base-class` → `toolchain.component-base-class`\n   - Drop: modules, source, output, component.registration\n4. If `repos:` section exists in `.ai\u002Fconfig.yaml`:\n   - For each repo entry, if `capabilities:` exists but `role:` does not:\n     - Derive role from capabilities: if capabilities includes both fe and be → fullstack; fe only → frontend; be only → backend; neither → config\n     - Add `role:` field, remove `capabilities:`\n5. Write updated `.ai\u002Fconfig.yaml`\n6. Rename `.ai\u002Fproject.yaml` → `.ai\u002Fproject.yaml.migrated`\n7. Report: \"Migrated project.yaml fields to config.yaml. Old file renamed to project.yaml.migrated.\"\n\n## 2. Resolve Plugin Directories\n\nFind each plugin root directory (same method as dx-doctor):\n\n- **dx plugin:** Glob for `**\u002Fskills\u002Fdx-doctor\u002FSKILL.md`, navigate up 3 levels\n- **aem plugin:** Glob for `**\u002Fskills\u002Faem-init\u002FSKILL.md`, navigate up 3 levels\n- **auto plugin:** Glob for `**\u002Fskills\u002Fauto-init\u002FSKILL.md`, navigate up 3 levels\n\n## 3. Apply Auto-fixes\n\nThese are plugin-owned files — update without asking.\n\n### 3a. Utility Scripts\n\n**Discovery (mirrors dx-doctor section 1d — never hardcode the file list).** Glob `\u003Cdx-plugin>\u002Fdata\u002Flib\u002F*.sh` and `\u003Cdx-plugin>\u002Fdata\u002Flib\u002F*.js`, excluding `*.test.sh`, `*.test.js`, and anything under `\u003Cdx-plugin>\u002Fdata\u002Flib\u002Ffixtures\u002F`. The remaining files plus the always-present hook form the utility manifest:\n\n- `.ai\u002Flib\u002F\u003Cbasename>` ← `\u003Cdx-plugin>\u002Fdata\u002Flib\u002F\u003Cbasename>` (one entry per discovered file)\n- `.claude\u002Fhooks\u002Fstop-guard.sh` ← `\u003Cdx-plugin>\u002Fdata\u002Fhooks\u002Fstop-guard.sh`\n\nFor each entry that dx-doctor reported as stale or missing, Read the plugin source file and Write it to the installed location. Then `chmod +x` only on `*.sh` files (do NOT chmod `*.js` — Node entry points are invoked via `node` and don't need the executable bit).\n\n**Comment-only differences:** If dx-doctor reported the script as `✓ up to date (project-specific examples)` — meaning the only differences are in comment lines where the project uses real infrastructure names (e.g., `kai-dedupe`) instead of the plugin's generic placeholders (e.g., `myai-dedupe`) — do NOT overwrite. The project-specific names are intentional and correct. Only update scripts that have functional code changes.\n\n**Functional local divergence (automation bundle) — NEVER silently clobber:** `.ai\u002Fautomation\u002F**` files (pipeline YAMLs, lambda handlers, scripts) are plugin-owned, but they are also where consumers prototype improvements *first* — e.g. a no-AI cron gate (`pr-answer-gate.sh`), a `refName` branch-pin in the WI-Router queue payload, extra pipeline steps, or a connection-name convention. Before overwriting any stale automation file, check whether its diff vs the plugin is **functional** (code\u002Flogic\u002Fsteps\u002Fstructure) or merely comment \u002F project-specific-name. If functional → do NOT auto-fix; reclassify as **Needs confirmation**, show the diff, and ask (default: keep local). Silently overwriting here erases the consumer's local work — this is the sync-clobber gap. Only auto-overwrite automation files whose diff is comment\u002Fname-only, or which the user explicitly confirms.\n\n### 3ab. Output Templates\n\nFor each stale or missing output template in `.ai\u002Ftemplates\u002F`:\n\nFor each subdirectory (`spec\u002F`, `wiki\u002F`, `ado-comments\u002F`):\n1. Create `.ai\u002Ftemplates\u002F\u003Csubdir>\u002F` if missing\n2. For each `*.template` file in `\u003Cdx-plugin>\u002Fdata\u002Ftemplates\u002F\u003Csubdir>\u002F`:\n   - Read the plugin source file, Write to `.ai\u002Ftemplates\u002F\u003Csubdir>\u002F\u003Cname>`\n\nThese are plugin-owned format definition files — always update without asking.\n\n### 3b. Universal Rules\n\n| Installed | Plugin Source |\n|-----------|-------------|\n| `.claude\u002Frules\u002Freuse-first.md` | `\u003Cdx-plugin>\u002Ftemplates\u002Frules\u002Funiversal-reuse-first.md.template` |\n\nRead template, Write to installed location.\n\n### 3c. Seed Data Refresh (if `.ai\u002Fproject\u002F` exists and `aem.docs-repo` is configured)\n\nSeed data files in `.ai\u002Fproject\u002F` are project-specific — they are NOT copied from a plugin directory. To refresh them, use `\u002Faem-refresh` which pulls from the docs repo or a local path.\n\nReport: `ℹ Seed data refresh is handled by \u002Faem-refresh, not dx-upgrade.`\n\n### 3c-ii. Config Migration\n\nCheck `dx.version` in `.ai\u002Fconfig.yaml`:\n- If missing or older than current plugin version:\n  1. Read the migration script from `\u003Cdx-plugin>\u002Fskills\u002Fdx-sync\u002Fscripts\u002Fmigrate-config.sh`\n  2. List pending migrations between current version and plugin version\n  3. For each pending migration, describe what will change and apply it (auto-fix — structural migrations don't need confirmation)\n  4. Update `dx.version` to current plugin version\n  5. Report: `✓ Config migrated from \u003Cold-version> → \u003Cnew-version>`\n- If already current: `✓ Config version up to date (\u003Cversion>)`\n\n**Migration script location:** `\u003Cdx-plugin>\u002Fskills\u002Fdx-sync\u002Fscripts\u002Fmigrate-config.sh` — this is the same script used by `\u002Fdx-sync`. Running `\u002Fdx-upgrade` on a single repo applies the same migrations that `\u002Fdx-sync` would apply across all consumers.\n\n### 3d. AEM Rule Files (if aem plugin configured)\n\nUse a recursive glob to find all templates: `\u003Caem-plugin>\u002Ftemplates\u002Frules\u002F**\u002F*.md.template`\n\nFor each `.md.template` file found:\n- Strip the `.template` extension to get the destination filename\n- Preserve subdirectory structure under `\u003Caem-plugin>\u002Ftemplates\u002Frules\u002F` → `.claude\u002Frules\u002F`\n  - Example: `shared\u002Faudit.md.template` → `.claude\u002Frules\u002Faudit.md`\n  - Example: `shared\u002Fqa-basic-auth.md.template` → `.claude\u002Frules\u002Fqa-basic-auth.md`\n  - Example: `be\u002Fbe-components.md.template` → `.claude\u002Frules\u002Fbe-components.md`\n  - Example: `fe\u002Ffe-tokens.md.template` → `.claude\u002Frules\u002Ffe-tokens.md`\n- Read source, Write to destination (flattening the subdir — destination is always directly under `.claude\u002Frules\u002F`, not in a subdir)\n\n### 3d-ii. Playwright browser migration (v3.0.0+, if aem plugin configured)\n\n**Breaking change in dx-aem v3.0.0:** AEM browser automation moved from `chrome-devtools-mcp` to `@playwright\u002Fmcp` (server `playwright`). If upgrading **from a v2.x** dx-aem:\n\n1. **Install the Playwright browser** (the server is bundled with the plugin but its Chromium is not):\n   ```bash\n   npx playwright install chromium\n   ```\n   Without it, `\u002Faem-verify`, `\u002Faem-qa`, `\u002Faem-fe-verify`, and `\u002Faem-editorial-guide` fail at first navigation.\n2. **Install the auth helper** if missing: copy `\u003Caem-plugin>\u002Fdata\u002Flib\u002Faem-playwright-auth.sh` → `.ai\u002Flib\u002F` (`chmod +x`) and ensure `.gitignore` has `.ai\u002Fplaywright\u002F`.\n3. **Report as manual-action:** `dx-perf` was removed in v3 (no replacement yet). Any local `.claude\u002Fskills\u002Fdx-perf\u002F` shadow or scripts referencing chrome-devtools tool names (`mcp__plugin_dx-aem_chrome-devtools-mcp__*`) must be updated to `mcp__plugin_dx-aem_playwright__browser_*`.\n\n### 3e. Copilot Agents and Skills\n\nIf `.github\u002Fagents\u002F` exists (Copilot was enabled):\n\n**Agents:** Run the agent install script:\n```bash\nbash \u003Cdx-plugin>\u002Fskills\u002Fdx-init\u002Fscripts\u002Finstall-copilot-agents.sh --force \u003Cdx-plugin>\n```\nThe `--force` flag overwrites stale agents with latest templates.\n\n### 3e-ii. Copilot Repo Hooks (`.github\u002Fhooks\u002F`)\n\nIf dx-doctor step 6.5d reported any `dx:` finding, repair in place:\n\n```bash\nbash \u003Cdx-plugin>\u002Fskills\u002Fdx-doctor\u002Fscripts\u002Frepo-hooks-audit.sh --fix .\n```\n\nWhat `--fix` changes, in every `.github\u002Fhooks\u002F*.json`, and nothing else:\n- removes the plugin-root entries older dx-init installs wrote (`session-start.sh`, `next-step.sh`, `validate-plugin-edit.sh`) and drops events left empty\n- replaces a stale dx branch guard (permission-rule matcher, `exit 1`, no `git commit` stdin filter) with the template's, matcher included\n- drops duplicate dx guards; adds the branch guard \u002F agentStop guard to `hooks.json` if missing\n\nHooks it does not recognise as dx entries are left byte-for-byte. It then re-runs the check and prints what is left — those rows are not dx entries: list each under **Manual Actions Required** with its detail. Exit 2 means a file is not valid JSON; it is left untouched — manual action.\n\nReport as `- .github\u002Fhooks\u002Fhooks.json ← repaired (\u003CN> dx entries)` under **Updated**.\n\n### 3f. Template-Generated Files\n\nFor missing (not stale) template-generated files:\n\n| Missing File | Plugin Source | Action |\n|-------------|-------------|--------|\n| `.ai\u002Fme.md` | — | Create with the demo template (same as dx-init step 5e) |\n\n### 3g. Settings\n\nIf `.claude\u002Fsettings.json` is missing or lacks `attribution`:\n- If file missing: Write `{\"attribution\": {\"commit\": \"\", \"pr\": \"\"}}`\n- If file exists but no attribution: Read, add `attribution` key, Write back (preserve other settings)\n\n### 3g-ii. Local Secrets File\n\nCheck `.claude\u002Fsettings.local.json`:\n- **If missing:** Create with empty env vars (same as dx-init step 5i). Report \"Created `.claude\u002Fsettings.local.json`\".\n- **If exists:** Parse and merge any new env var keys that the upgraded plugin now requires (empty string value). Do NOT overwrite existing values. Base vars: `QA_BASIC_AUTH_USER`, `QA_BASIC_AUTH_PASS`, `QA_BASIC_AUTH_FALLBACK_USER`, `QA_BASIC_AUTH_FALLBACK_PASS`, `AXE_API_KEY`. If project has `aem:` section in config, also add: `AEM_INSTANCES` (with default value `local:http:\u002F\u002Flocalhost:4502:admin:admin,qa:https:\u002F\u002Fqa-author.example.com:USER:PASS`). Report count of new keys added (or \"up to date\").\n\n### 3h. MCP Configuration (ADO only)\n\nIf `.mcp.json` org mismatch was detected:\n- Read `.mcp.json`, update the org in the `ado` server args, Write back\n\nIf `.mcp.json` is missing and `scm.provider` is `ado`:\n- Create with ADO MCP entry using `scm.org` from config\n\n## 4. Handle Customized Files (needs confirmation)\n\nFor each file flagged as \"needs confirmation\" — these are files the user may have intentionally edited:\n\n### 4a. Shared Rules (`.ai\u002Frules\u002F*.md`)\n\nFor each stale shared rule:\n1. Read the installed file\n2. Read the plugin template (`\u003Cdx-plugin>\u002Ftemplates\u002Frules\u002F\u003Cname>.md.template`)\n3. Present a summary: \"This file differs from the latest plugin template.\"\n4. Ask:\n   - **(A) Update to latest template** — overwrites with plugin template\n   - **(B) Keep current version** — no changes\n   - **(C) Show diff** — display both versions, then ask A or B\n\nIf the file has AEM sections appended (for `pr-review.md` and `pr-answer.md`):\n- When updating, preserve the AEM section — replace only the dx template portion (everything before the first `## AEM` or `## Sling` heading)\n- Explain this to the user: \"The AEM section will be preserved. Only the dx portion is being updated.\"\n\n### 4b. AEM Convention Rules (`.claude\u002Frules\u002F`)\n\nFor each stale AEM rule found via `\u003Caem-plugin>\u002Ftemplates\u002Frules\u002F**\u002F*.md.template` (e.g., `be\u002Fbe-*.md.template`, `fe\u002Ffe-*.md.template`, `shared\u002Fnaming.md.template`, `shared\u002Faccessibility.md.template`):\n1. Read installed file (`.claude\u002Frules\u002F\u003Cname>.md`) and corresponding template\n2. Ask same A\u002FB\u002FC as above\n\n### 4c. Automation Policy (if applicable)\n\nIf `.ai\u002Fautomation\u002Fpolicy\u002Fpipeline-policy.yaml` is flagged:\n1. Read installed and plugin source\n2. Ask same A\u002FB\u002FC — this file may have user-tuned rate limits or capability gates\n\n### 4d. Automation Profile Awareness\n\nWhen upgrading automation files, read `automationProfile` from `.ai\u002Fautomation\u002Finfra.json` (if it exists).\n\n- **Legacy profiles** (`consumer`, `pr-only`, `pr-delegation`): Add manual action: \"Run `\u002Fauto-init` to migrate to per-project model.\" Do NOT flag missing Lambda handlers as errors — they may be intentionally absent in legacy consumer installs. DO check that `webhooks.pr-answer` entry exists in infra.json — if missing, add manual action: \"Run `\u002Fauto-webhooks` to create repo-scoped PR Answer hook.\"\n- **`per-project` or missing profile field:** Check all automation files against enabled agents in infra.json. Lambda handlers are expected if any Lambda-based agents are enabled.\n\n### 4e. Webhook Migration (v2.10+)\n\nIf `.ai\u002Fautomation\u002Finfra.json` exists and has `webhooks.pr-answer` WITHOUT a `filter` field containing `repository`:\n- Report as manual action: \"PR Answer hook may be project-scoped (legacy). Run `\u002Fauto-webhooks` to create a repo-scoped hook filtered to this repo + base branch.\"\n\nThis applies to both hub and consumer profiles — all repos should have their own repo-scoped PR Answer hook.\n\n## 5. Report Manual Actions\n\nList all issues that cannot be auto-fixed. These require the user to take action:\n\n```markdown\n### Manual Actions Required\n\n1. **Add to .gitignore:** `.ai\u002Frun-context\u002F`\n2. **Run \u002Faem-init:** project seed data is missing\n3. **Run \u002Fauto-init:** .ai\u002Fautomation\u002Finfra.json not found\n4. **Verify branch:** scm.base-branch 'develop' not found in remotes — check .ai\u002Fconfig.yaml\n5. **Check build config:** build.command uses 'mvn' but pom.xml not found\n```\n\nFor missing config sections, always suggest running the appropriate init skill — dx-upgrade does not create config sections (that requires interactive user input from the init flow).\n\n## 6. Summary Report\n\n```markdown\n## Upgrade Complete\n\n| Action | Count |\n|--------|-------|\n| Files updated | 5 |\n| Files created | 1 |\n| Files skipped (kept by user) | 1 |\n| Manual actions remaining | 2 |\n\n### Updated\n- .ai\u002Flib\u002Faudit.sh ← from plugin\n- .claude\u002Fhooks\u002Fstop-guard.sh ← from plugin\n- .ai\u002Fproject\u002Fcomponent-index.md ← from plugin data\n- .ai\u002Fproject\u002Fmarkets.md ← from plugin data\n- .claude\u002Frules\u002Fbe-components.md ← from plugin template\n\n### Created\n- .ai\u002Fme.md ← demo template\n\n### Kept (user's version)\n- .ai\u002Frules\u002Fpr-review.md\n\n### Manual Actions Required\n1. Add `.ai\u002Frun-context\u002F` to .gitignore\n2. Verify `scm.base-branch` in .ai\u002Fconfig.yaml\n\n→ Run \u002Fdx-doctor to verify\n```\n\n## Examples\n\n1. `\u002Fdx-upgrade all` — Runs dx-doctor across all plugins, finds 3 stale utility scripts and 2 missing Copilot agents. Presents the fix plan, auto-updates plugin-owned files, shows diffs for 1 customized rule file (user chooses \"Keep\"), and lists 1 manual action (missing gitignore entry).\n\n2. `\u002Fdx-upgrade dx` — Scopes the upgrade to only the dx-core plugin. Updates `audit.sh` and `stop-guard.sh` from plugin data, installs 4 new Copilot skill templates, and reports \"Suggest re-run: `\u002Fdx-doctor` to verify.\"\n\n3. `\u002Fdx-upgrade aem` — Scopes to the dx-aem plugin. Updates stale AEM convention rules in `.claude\u002Frules\u002F`, preserves user-customized `pr-review.md` AEM section, and reports seed data refresh should be done via `\u002Faem-refresh`.\n\n## Copilot CLI Plugin Update\n\nCopilot CLI's `\u002Fplugin marketplace update` may fail for local marketplaces with \"Failed to fetch git marketplace\". To update plugins in Copilot CLI, uninstall and reinstall:\n\n```bash\n\u002Fplugin uninstall dx-core\n\u002Fplugin uninstall dx-aem\n\u002Fplugin install dx-core@dx-aem-flow\n\u002Fplugin install dx-aem@dx-aem-flow\n```\n\nThis picks up the latest version from the local marketplace source.\n\n## Troubleshooting\n\n- **\"All checks passed. Nothing to upgrade.\"**\n  **Cause:** All project files match the latest plugin versions.\n  **Fix:** No action needed. This is the desired state after a successful upgrade.\n\n- **Customized rule file shows unexpected diff**\n  **Cause:** Both the plugin template and the user have made changes to the same file.\n  **Fix:** Choose option (C) \"Show diff\" to see both versions side by side, then decide to keep your version or replace with the template. You can also choose to write the template as `.template` and manually merge.\n\n- **\"Missing config section\" reported as manual action**\n  **Cause:** A newer plugin version introduced a config section (e.g., `aem:` or `automation:`) that doesn't exist in your `.ai\u002Fconfig.yaml`.\n  **Fix:** Run the appropriate init skill (`\u002Faem-init`, `\u002Fauto-init`) to interactively add the missing config section.\n\n## Rules\n\n- **Doctor first** — always run dx-doctor before applying any fixes\n- **Confirm before overwriting customized files** — auto-fix plugin-owned files; ask for user-editable files\n- **Never touch config values** — update file structure and template content, never change user-entered config values in config.yaml\n- **Never touch me.md content** — only create if missing (use demo template)\n- **Preserve AEM sections** — when updating shared rules that have AEM sections appended, keep the AEM portion intact\n- **Preserve user data in infra.json\u002Frepos.json** — never overwrite these automation config files\n- **Report everything** — show what was changed, what was skipped, and what needs manual action\n- **Suggest re-run** — always end with \"Run `\u002Fdx-doctor` to verify\"\n- **Gitignore is sacred** — never auto-modify .gitignore; list needed entries as manual actions\n- **Template-driven** — always Read source files from plugin directories; never hardcode file content\n- **chmod +x** — always set executable permission on shell scripts after copying\n","You upgrade a consumer project's dx workflow files to match the latest installed plugin versions. You diagnose first (dx-doctor), then fix issues with smart handling of user-customized files.\n\n## Tool Usage Rules\n\n- **File existence:** Use `Glob` — never `[ -f ]`, `test -f`, or Bash test commands\n- **File content reads:** Use `Read` — never `cat` or `head` in Bash\n- **File writes:** Use `Write` — never `echo >` or `cat \u003C\u003CEOF` in Bash\n- **Content comparison:** Read both files with `Read`, compare in-context — never shell `diff`\n- **Bash is ONLY for:** `chmod +x` on scripts, `bash` to run install\u002Frepair scripts (steps 3e, 3e-ii), and `git` commands\n- **Parallel operations:** Call multiple `Read`\u002F`Write`\u002F`Glob` tools in parallel when independent — do not serialize into one Bash command with `&&`\u002F`||`\n\n## 0. Run dx-doctor\n\nRun the full `\u002Fdx-doctor` flow inline with the same scope argument the user passed. Collect all issues into three categories:\n\n| Category | Description | Examples |\n|----------|-------------|---------|\n| **Auto-fix** | Plugin-owned files that can be updated without asking | Stale utility scripts, stale seed data, stale universal rules, missing template-generated files |\n| **Needs confirmation** | Files the user may have intentionally customized | Stale shared rules (`.ai\u002Frules\u002F*`), stale AEM convention rules, **automation bundle files with functional local divergence** (`.ai\u002Fautomation\u002F**` pipeline YAMLs, lambda handlers, scripts — consumers often prototype steps\u002Fgates\u002Fbranch-pins ahead of the plugin) |\n| **Manual action** | Issues that cannot be auto-fixed | Missing gitignore entries, missing config sections, broken branch references |\n\nIf dx-doctor reports zero issues:\n```\n✓ All checks passed. Nothing to upgrade.\n```\nSTOP.\n\n## 1. Present Fix Plan\n\nBefore applying any fixes, present a summary table for each category:\n\n```markdown\n## Upgrade Plan\n\n### Auto-fix (no confirmation needed)\n| File | Issue | Fix |\n|------|-------|-----|\n| .ai\u002Flib\u002Faudit.sh | stale | Update from plugin |\n| .ai\u002Fproject\u002Fcomponent-index.md | stale | Update from plugin data |\n| .github\u002Fagents\u002F | 4 new, 2 stale | Install new + update stale from templates |\n| .github\u002Fhooks\u002Fhooks.json | 3 dx entries need a plugin root | Repair with repo-hooks-audit.sh --fix |\n\n### Needs confirmation\n| File | Issue | Action |\n|------|-------|--------|\n| .ai\u002Frules\u002Fpr-answer.md | stale | Show diff, ask |\n| .claude\u002Frules\u002Fbe-components.md | stale | Show diff, ask |\n\n### Manual action required\n| Issue | Suggested Fix |\n|-------|--------------|\n| .ai\u002Frun-context\u002F not in .gitignore | Add to .gitignore manually |\n| Missing project seed data | Run \u002Faem-init or \u002Faem-refresh |\n```\n\nAsk: **Proceed with auto-fixes?** (the confirmation items will be handled one-by-one next)\n\nIf the user declines, STOP.\n\n## 1b. Migrate project.yaml (if exists)\n\nIf `.ai\u002Fproject.yaml` exists (NOT `.ai\u002Fproject\u002Fproject.yaml`):\n\n1. Read `.ai\u002Fproject.yaml`\n2. Read `.ai\u002Fconfig.yaml`\n3. Merge fields per mapping:\n   - `type` → `project.type` (add to project: section)\n   - `role` → `project.role` (derive from type if not set: aem-frontend→frontend, aem-fullstack→fullstack, java→backend)\n   - `toolchain.*` → `toolchain:` section (add new top-level section)\n   - `build.serve` → `build.serve` (add if not present)\n   - `build.lint-js` → `build.lint-js` (add if not present)\n   - `build.lint-scss` → `build.lint-scss` (add if not present)\n   - `build.lint-fix` → `build.lint-fix` (add if not present)\n   - `component.base-class` → `toolchain.component-base-class`\n   - Drop: modules, source, output, component.registration\n4. If `repos:` section exists in `.ai\u002Fconfig.yaml`:\n   - For each repo entry, if `capabilities:` exists but `role:` does not:\n     - Derive role from capabilities: if capabilities includes both fe and be → fullstack; fe only → frontend; be only → backend; neither → config\n     - Add `role:` field, remove `capabilities:`\n5. Write updated `.ai\u002Fconfig.yaml`\n6. Rename `.ai\u002Fproject.yaml` → `.ai\u002Fproject.yaml.migrated`\n7. Report: \"Migrated project.yaml fields to config.yaml. Old file renamed to project.yaml.migrated.\"\n\n## 2. Resolve Plugin Directories\n\nFind each plugin root directory (same method as dx-doctor):\n\n- **dx plugin:** Glob for `**\u002Fskills\u002Fdx-doctor\u002FSKILL.md`, navigate up 3 levels\n- **aem plugin:** Glob for `**\u002Fskills\u002Faem-init\u002FSKILL.md`, navigate up 3 levels\n- **auto plugin:** Glob for `**\u002Fskills\u002Fauto-init\u002FSKILL.md`, navigate up 3 levels\n\n## 3. Apply Auto-fixes\n\nThese are plugin-owned files — update without asking.\n\n### 3a. Utility Scripts\n\n**Discovery (mirrors dx-doctor section 1d — never hardcode the file list).** Glob `\u003Cdx-plugin>\u002Fdata\u002Flib\u002F*.sh` and `\u003Cdx-plugin>\u002Fdata\u002Flib\u002F*.js`, excluding `*.test.sh`, `*.test.js`, and anything under `\u003Cdx-plugin>\u002Fdata\u002Flib\u002Ffixtures\u002F`. The remaining files plus the always-present hook form the utility manifest:\n\n- `.ai\u002Flib\u002F\u003Cbasename>` ← `\u003Cdx-plugin>\u002Fdata\u002Flib\u002F\u003Cbasename>` (one entry per discovered file)\n- `.claude\u002Fhooks\u002Fstop-guard.sh` ← `\u003Cdx-plugin>\u002Fdata\u002Fhooks\u002Fstop-guard.sh`\n\nFor each entry that dx-doctor reported as stale or missing, Read the plugin source file and Write it to the installed location. Then `chmod +x` only on `*.sh` files (do NOT chmod `*.js` — Node entry points are invoked via `node` and don't need the executable bit).\n\n**Comment-only differences:** If dx-doctor reported the script as `✓ up to date (project-specific examples)` — meaning the only differences are in comment lines where the project uses real infrastructure names (e.g., `kai-dedupe`) instead of the plugin's generic placeholders (e.g., `myai-dedupe`) — do NOT overwrite. The project-specific names are intentional and correct. Only update scripts that have functional code changes.\n\n**Functional local divergence (automation bundle) — NEVER silently clobber:** `.ai\u002Fautomation\u002F**` files (pipeline YAMLs, lambda handlers, scripts) are plugin-owned, but they are also where consumers prototype improvements *first* — e.g. a no-AI cron gate (`pr-answer-gate.sh`), a `refName` branch-pin in the WI-Router queue payload, extra pipeline steps, or a connection-name convention. Before overwriting any stale automation file, check whether its diff vs the plugin is **functional** (code\u002Flogic\u002Fsteps\u002Fstructure) or merely comment \u002F project-specific-name. If functional → do NOT auto-fix; reclassify as **Needs confirmation**, show the diff, and ask (default: keep local). Silently overwriting here erases the consumer's local work — this is the sync-clobber gap. Only auto-overwrite automation files whose diff is comment\u002Fname-only, or which the user explicitly confirms.\n\n### 3ab. Output Templates\n\nFor each stale or missing output template in `.ai\u002Ftemplates\u002F`:\n\nFor each subdirectory (`spec\u002F`, `wiki\u002F`, `ado-comments\u002F`):\n1. Create `.ai\u002Ftemplates\u002F\u003Csubdir>\u002F` if missing\n2. For each `*.template` file in `\u003Cdx-plugin>\u002Fdata\u002Ftemplates\u002F\u003Csubdir>\u002F`:\n   - Read the plugin source file, Write to `.ai\u002Ftemplates\u002F\u003Csubdir>\u002F\u003Cname>`\n\nThese are plugin-owned format definition files — always update without asking.\n\n### 3b. Universal Rules\n\n| Installed | Plugin Source |\n|-----------|-------------|\n| `.claude\u002Frules\u002Freuse-first.md` | `\u003Cdx-plugin>\u002Ftemplates\u002Frules\u002Funiversal-reuse-first.md.template` |\n\nRead template, Write to installed location.\n\n### 3c. Seed Data Refresh (if `.ai\u002Fproject\u002F` exists and `aem.docs-repo` is configured)\n\nSeed data files in `.ai\u002Fproject\u002F` are project-specific — they are NOT copied from a plugin directory. To refresh them, use `\u002Faem-refresh` which pulls from the docs repo or a local path.\n\nReport: `ℹ Seed data refresh is handled by \u002Faem-refresh, not dx-upgrade.`\n\n### 3c-ii. Config Migration\n\nCheck `dx.version` in `.ai\u002Fconfig.yaml`:\n- If missing or older than current plugin version:\n  1. Read the migration script from `\u003Cdx-plugin>\u002Fskills\u002Fdx-sync\u002Fscripts\u002Fmigrate-config.sh`\n  2. List pending migrations between current version and plugin version\n  3. For each pending migration, describe what will change and apply it (auto-fix — structural migrations don't need confirmation)\n  4. Update `dx.version` to current plugin version\n  5. Report: `✓ Config migrated from \u003Cold-version> → \u003Cnew-version>`\n- If already current: `✓ Config version up to date (\u003Cversion>)`\n\n**Migration script location:** `\u003Cdx-plugin>\u002Fskills\u002Fdx-sync\u002Fscripts\u002Fmigrate-config.sh` — this is the same script used by `\u002Fdx-sync`. Running `\u002Fdx-upgrade` on a single repo applies the same migrations that `\u002Fdx-sync` would apply across all consumers.\n\n### 3d. AEM Rule Files (if aem plugin configured)\n\nUse a recursive glob to find all templates: `\u003Caem-plugin>\u002Ftemplates\u002Frules\u002F**\u002F*.md.template`\n\nFor each `.md.template` file found:\n- Strip the `.template` extension to get the destination filename\n- Preserve subdirectory structure under `\u003Caem-plugin>\u002Ftemplates\u002Frules\u002F` → `.claude\u002Frules\u002F`\n  - Example: `shared\u002Faudit.md.template` → `.claude\u002Frules\u002Faudit.md`\n  - Example: `shared\u002Fqa-basic-auth.md.template` → `.claude\u002Frules\u002Fqa-basic-auth.md`\n  - Example: `be\u002Fbe-components.md.template` → `.claude\u002Frules\u002Fbe-components.md`\n  - Example: `fe\u002Ffe-tokens.md.template` → `.claude\u002Frules\u002Ffe-tokens.md`\n- Read source, Write to destination (flattening the subdir — destination is always directly under `.claude\u002Frules\u002F`, not in a subdir)\n\n### 3d-ii. Playwright browser migration (v3.0.0+, if aem plugin configured)\n\n**Breaking change in dx-aem v3.0.0:** AEM browser automation moved from `chrome-devtools-mcp` to `@playwright\u002Fmcp` (server `playwright`). If upgrading **from a v2.x** dx-aem:\n\n1. **Install the Playwright browser** (the server is bundled with the plugin but its Chromium is not):\n   ```bash\n   npx playwright install chromium\n   ```\n   Without it, `\u002Faem-verify`, `\u002Faem-qa`, `\u002Faem-fe-verify`, and `\u002Faem-editorial-guide` fail at first navigation.\n2. **Install the auth helper** if missing: copy `\u003Caem-plugin>\u002Fdata\u002Flib\u002Faem-playwright-auth.sh` → `.ai\u002Flib\u002F` (`chmod +x`) and ensure `.gitignore` has `.ai\u002Fplaywright\u002F`.\n3. **Report as manual-action:** `dx-perf` was removed in v3 (no replacement yet). Any local `.claude\u002Fskills\u002Fdx-perf\u002F` shadow or scripts referencing chrome-devtools tool names (`mcp__plugin_dx-aem_chrome-devtools-mcp__*`) must be updated to `mcp__plugin_dx-aem_playwright__browser_*`.\n\n### 3e. Copilot Agents and Skills\n\nIf `.github\u002Fagents\u002F` exists (Copilot was enabled):\n\n**Agents:** Run the agent install script:\n```bash\nbash \u003Cdx-plugin>\u002Fskills\u002Fdx-init\u002Fscripts\u002Finstall-copilot-agents.sh --force \u003Cdx-plugin>\n```\nThe `--force` flag overwrites stale agents with latest templates.\n\n### 3e-ii. Copilot Repo Hooks (`.github\u002Fhooks\u002F`)\n\nIf dx-doctor step 6.5d reported any `dx:` finding, repair in place:\n\n```bash\nbash \u003Cdx-plugin>\u002Fskills\u002Fdx-doctor\u002Fscripts\u002Frepo-hooks-audit.sh --fix .\n```\n\nWhat `--fix` changes, in every `.github\u002Fhooks\u002F*.json`, and nothing else:\n- removes the plugin-root entries older dx-init installs wrote (`session-start.sh`, `next-step.sh`, `validate-plugin-edit.sh`) and drops events left empty\n- replaces a stale dx branch guard (permission-rule matcher, `exit 1`, no `git commit` stdin filter) with the template's, matcher included\n- drops duplicate dx guards; adds the branch guard \u002F agentStop guard to `hooks.json` if missing\n\nHooks it does not recognise as dx entries are left byte-for-byte. It then re-runs the check and prints what is left — those rows are not dx entries: list each under **Manual Actions Required** with its detail. Exit 2 means a file is not valid JSON; it is left untouched — manual action.\n\nReport as `- .github\u002Fhooks\u002Fhooks.json ← repaired (\u003CN> dx entries)` under **Updated**.\n\n### 3f. Template-Generated Files\n\nFor missing (not stale) template-generated files:\n\n| Missing File | Plugin Source | Action |\n|-------------|-------------|--------|\n| `.ai\u002Fme.md` | — | Create with the demo template (same as dx-init step 5e) |\n\n### 3g. Settings\n\nIf `.claude\u002Fsettings.json` is missing or lacks `attribution`:\n- If file missing: Write `{\"attribution\": {\"commit\": \"\", \"pr\": \"\"}}`\n- If file exists but no attribution: Read, add `attribution` key, Write back (preserve other settings)\n\n### 3g-ii. Local Secrets File\n\nCheck `.claude\u002Fsettings.local.json`:\n- **If missing:** Create with empty env vars (same as dx-init step 5i). Report \"Created `.claude\u002Fsettings.local.json`\".\n- **If exists:** Parse and merge any new env var keys that the upgraded plugin now requires (empty string value). Do NOT overwrite existing values. Base vars: `QA_BASIC_AUTH_USER`, `QA_BASIC_AUTH_PASS`, `QA_BASIC_AUTH_FALLBACK_USER`, `QA_BASIC_AUTH_FALLBACK_PASS`, `AXE_API_KEY`. If project has `aem:` section in config, also add: `AEM_INSTANCES` (with default value `local:http:\u002F\u002Flocalhost:4502:admin:admin,qa:https:\u002F\u002Fqa-author.example.com:USER:PASS`). Report count of new keys added (or \"up to date\").\n\n### 3h. MCP Configuration (ADO only)\n\nIf `.mcp.json` org mismatch was detected:\n- Read `.mcp.json`, update the org in the `ado` server args, Write back\n\nIf `.mcp.json` is missing and `scm.provider` is `ado`:\n- Create with ADO MCP entry using `scm.org` from config\n\n## 4. Handle Customized Files (needs confirmation)\n\nFor each file flagged as \"needs confirmation\" — these are files the user may have intentionally edited:\n\n### 4a. Shared Rules (`.ai\u002Frules\u002F*.md`)\n\nFor each stale shared rule:\n1. Read the installed file\n2. Read the plugin template (`\u003Cdx-plugin>\u002Ftemplates\u002Frules\u002F\u003Cname>.md.template`)\n3. Present a summary: \"This file differs from the latest plugin template.\"\n4. Ask:\n   - **(A) Update to latest template** — overwrites with plugin template\n   - **(B) Keep current version** — no changes\n   - **(C) Show diff** — display both versions, then ask A or B\n\nIf the file has AEM sections appended (for `pr-review.md` and `pr-answer.md`):\n- When updating, preserve the AEM section — replace only the dx template portion (everything before the first `## AEM` or `## Sling` heading)\n- Explain this to the user: \"The AEM section will be preserved. Only the dx portion is being updated.\"\n\n### 4b. AEM Convention Rules (`.claude\u002Frules\u002F`)\n\nFor each stale AEM rule found via `\u003Caem-plugin>\u002Ftemplates\u002Frules\u002F**\u002F*.md.template` (e.g., `be\u002Fbe-*.md.template`, `fe\u002Ffe-*.md.template`, `shared\u002Fnaming.md.template`, `shared\u002Faccessibility.md.template`):\n1. Read installed file (`.claude\u002Frules\u002F\u003Cname>.md`) and corresponding template\n2. Ask same A\u002FB\u002FC as above\n\n### 4c. Automation Policy (if applicable)\n\nIf `.ai\u002Fautomation\u002Fpolicy\u002Fpipeline-policy.yaml` is flagged:\n1. Read installed and plugin source\n2. Ask same A\u002FB\u002FC — this file may have user-tuned rate limits or capability gates\n\n### 4d. Automation Profile Awareness\n\nWhen upgrading automation files, read `automationProfile` from `.ai\u002Fautomation\u002Finfra.json` (if it exists).\n\n- **Legacy profiles** (`consumer`, `pr-only`, `pr-delegation`): Add manual action: \"Run `\u002Fauto-init` to migrate to per-project model.\" Do NOT flag missing Lambda handlers as errors — they may be intentionally absent in legacy consumer installs. DO check that `webhooks.pr-answer` entry exists in infra.json — if missing, add manual action: \"Run `\u002Fauto-webhooks` to create repo-scoped PR Answer hook.\"\n- **`per-project` or missing profile field:** Check all automation files against enabled agents in infra.json. Lambda handlers are expected if any Lambda-based agents are enabled.\n\n### 4e. Webhook Migration (v2.10+)\n\nIf `.ai\u002Fautomation\u002Finfra.json` exists and has `webhooks.pr-answer` WITHOUT a `filter` field containing `repository`:\n- Report as manual action: \"PR Answer hook may be project-scoped (legacy). Run `\u002Fauto-webhooks` to create a repo-scoped hook filtered to this repo + base branch.\"\n\nThis applies to both hub and consumer profiles — all repos should have their own repo-scoped PR Answer hook.\n\n## 5. Report Manual Actions\n\nList all issues that cannot be auto-fixed. These require the user to take action:\n\n```markdown\n### Manual Actions Required\n\n1. **Add to .gitignore:** `.ai\u002Frun-context\u002F`\n2. **Run \u002Faem-init:** project seed data is missing\n3. **Run \u002Fauto-init:** .ai\u002Fautomation\u002Finfra.json not found\n4. **Verify branch:** scm.base-branch 'develop' not found in remotes — check .ai\u002Fconfig.yaml\n5. **Check build config:** build.command uses 'mvn' but pom.xml not found\n```\n\nFor missing config sections, always suggest running the appropriate init skill — dx-upgrade does not create config sections (that requires interactive user input from the init flow).\n\n## 6. Summary Report\n\n```markdown\n## Upgrade Complete\n\n| Action | Count |\n|--------|-------|\n| Files updated | 5 |\n| Files created | 1 |\n| Files skipped (kept by user) | 1 |\n| Manual actions remaining | 2 |\n\n### Updated\n- .ai\u002Flib\u002Faudit.sh ← from plugin\n- .claude\u002Fhooks\u002Fstop-guard.sh ← from plugin\n- .ai\u002Fproject\u002Fcomponent-index.md ← from plugin data\n- .ai\u002Fproject\u002Fmarkets.md ← from plugin data\n- .claude\u002Frules\u002Fbe-components.md ← from plugin template\n\n### Created\n- .ai\u002Fme.md ← demo template\n\n### Kept (user's version)\n- .ai\u002Frules\u002Fpr-review.md\n\n### Manual Actions Required\n1. Add `.ai\u002Frun-context\u002F` to .gitignore\n2. Verify `scm.base-branch` in .ai\u002Fconfig.yaml\n\n→ Run \u002Fdx-doctor to verify\n```\n\n## Examples\n\n1. `\u002Fdx-upgrade all` — Runs dx-doctor across all plugins, finds 3 stale utility scripts and 2 missing Copilot agents. Presents the fix plan, auto-updates plugin-owned files, shows diffs for 1 customized rule file (user chooses \"Keep\"), and lists 1 manual action (missing gitignore entry).\n\n2. `\u002Fdx-upgrade dx` — Scopes the upgrade to only the dx-core plugin. Updates `audit.sh` and `stop-guard.sh` from plugin data, installs 4 new Copilot skill templates, and reports \"Suggest re-run: `\u002Fdx-doctor` to verify.\"\n\n3. `\u002Fdx-upgrade aem` — Scopes to the dx-aem plugin. Updates stale AEM convention rules in `.claude\u002Frules\u002F`, preserves user-customized `pr-review.md` AEM section, and reports seed data refresh should be done via `\u002Faem-refresh`.\n\n## Copilot CLI Plugin Update\n\nCopilot CLI's `\u002Fplugin marketplace update` may fail for local marketplaces with \"Failed to fetch git marketplace\". To update plugins in Copilot CLI, uninstall and reinstall:\n\n```bash\n\u002Fplugin uninstall dx-core\n\u002Fplugin uninstall dx-aem\n\u002Fplugin install dx-core@dx-aem-flow\n\u002Fplugin install dx-aem@dx-aem-flow\n```\n\nThis picks up the latest version from the local marketplace source.\n\n## Troubleshooting\n\n- **\"All checks passed. Nothing to upgrade.\"**\n  **Cause:** All project files match the latest plugin versions.\n  **Fix:** No action needed. This is the desired state after a successful upgrade.\n\n- **Customized rule file shows unexpected diff**\n  **Cause:** Both the plugin template and the user have made changes to the same file.\n  **Fix:** Choose option (C) \"Show diff\" to see both versions side by side, then decide to keep your version or replace with the template. You can also choose to write the template as `.template` and manually merge.\n\n- **\"Missing config section\" reported as manual action**\n  **Cause:** A newer plugin version introduced a config section (e.g., `aem:` or `automation:`) that doesn't exist in your `.ai\u002Fconfig.yaml`.\n  **Fix:** Run the appropriate init skill (`\u002Faem-init`, `\u002Fauto-init`) to interactively add the missing config section.\n\n## Rules\n\n- **Doctor first** — always run dx-doctor before applying any fixes\n- **Confirm before overwriting customized files** — auto-fix plugin-owned files; ask for user-editable files\n- **Never touch config values** — update file structure and template content, never change user-entered config values in config.yaml\n- **Never touch me.md content** — only create if missing (use demo template)\n- **Preserve AEM sections** — when updating shared rules that have AEM sections appended, keep the AEM portion intact\n- **Preserve user data in infra.json\u002Frepos.json** — never overwrite these automation config files\n- **Report everything** — show what was changed, what was skipped, and what needs manual action\n- **Suggest re-run** — always end with \"Run `\u002Fdx-doctor` to verify\"\n- **Gitignore is sacred** — never auto-modify .gitignore; list needed entries as manual actions\n- **Template-driven** — always Read source files from plugin directories; never hardcode file content\n- **chmod +x** — always set executable permission on shell scripts after copying\n",{"name":5,"description":7,"allowed-tools":49,"argument-hint":51},[36,34,41,35,50],"agent","[dx|aem|auto|all]","main","5c642842a92100dc7561ae0682a152a74846e186","plugins\u002Fdx-core\u002Fskills\u002Fdx-upgrade",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":62,"prompt":72,"zipAvailable":73},[63,66,69],{"tool":64,"command":65},"npx","npx skills add easingthemes\u002Fdx-aem-flow --skill dx-upgrade",{"tool":67,"command":68},"bunx","bunx skills add easingthemes\u002Fdx-aem-flow --skill dx-upgrade",{"tool":70,"command":71},"pnpm","pnpm dlx skills add easingthemes\u002Fdx-aem-flow --skill dx-upgrade","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-core\u002Fskills\u002Fdx-upgrade\u002FSKILL.md",true,[],[76,98,119,139,155,170],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":82,"publishedAt":44},"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",[],[24,83,84,85,86,87,88,89,90,91,29,92,93,94,95,36,35,96,97],"dx hub status","hub","status","hub status","which","show","for","ticket","clean","done","Bash","id","dispatch","repos","grep",{"skillNo":99,"name":100,"nameZh":6,"description":101,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":104,"publishedAt":44},"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",[],[105,106,24,107,84,108,109,110,111,112,113,114,115,116,93,117,118,36,35,34],"init","hub init","dx hub init","SET","time","mode","default","up","repo setup","orchestration","configure","multi-repo","cli","directory",{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":126,"publishedAt":44},"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",[125],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[24,127,95,84,128,89,129,130,131,90,132,133,29,134,93,135,136,137,94,138],"dx hub dispatch","ado","repo","work on","session","open","MCP","URL","vscode","code","across","work",{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":145,"publishedAt":44},"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",[],[24,146,84,147,88,148,129,149,150,151,152,29,115,93,153,36,154,35,34,96],"dx hub config","config","view","manage","trigger","true","adjust","terminal","settings",{"skillNo":156,"name":157,"nameZh":6,"description":158,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":159,"categories":160,"keywords":161,"publishedAt":44},"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",[],[162,24,163,96,87,129,137,164,94,165,138,166,84,167,168,169],"discover","dx discover repos","router","directive","simple","block","sonnet","table",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":176,"publishedAt":44},"01M6H483MFY4W4TPMWJJPG9JZW","dx-ticket-analyze","Research an ADO\u002FJira ticket and list the source files and assets it involves. Use for 'analyze ticket', 'what files does this touch?', 'find files for this story'.","https:\u002F\u002Fgithub.com\u002Feasingthemes\u002Fdx-aem-flow\u002Fblob\u002Fmain\u002Fplugins\u002Fdx-core\u002Fskills\u002Fdx-ticket-analyze\u002FSKILL.md",[],[90,177,24,178,41,39,134,138,179,36,35,180,34,181,33,182,183,184,128,89],"analyze","dx ticket analyze","haiku","jira","issue","source","atlassian","jira ticket"]