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.
- License 许可
- MIT
- 最近更新
- 2026-11-11
- Stars
- ★ 7
- Forks
- 3
01 前言 Front Matter
- name
- dx-upgrade
- description
- Upgrade a consumer project to the installed plugin versions — run dx-doctor, fix stale and missing files, list manual actions. Use after upgrading plugins.
- allowed-tools
- [ "read", "edit", "search", "write", "agent" ]
- argument-hint
- [dx|aem|auto|all]
03 SKILL.md 正文
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.
Tool Usage Rules
- File existence: Use
Glob— never[ -f ],test -f, or Bash test commands - File content reads: Use
Read— nevercatorheadin Bash - File writes: Use
Write— neverecho >orcat <<EOFin Bash - Content comparison: Read both files with
Read, compare in-context — never shelldiff - Bash is ONLY for:
chmod +xon scripts,bashto run install/repair scripts (steps 3e, 3e-ii), andgitcommands - Parallel operations: Call multiple
Read/Write/Globtools in parallel when independent — do not serialize into one Bash command with&&/||
0. Run dx-doctor
Run the full /dx-doctor flow inline with the same scope argument the user passed. Collect all issues into three categories:
| Category | Description | Examples |
|---|---|---|
| Auto-fix | Plugin-owned files that can be updated without asking | Stale utility scripts, stale seed data, stale universal rules, missing template-generated files |
| Needs confirmation | Files the user may have intentionally customized | Stale shared rules (.ai/rules/*), stale AEM convention rules, automation bundle files with functional local divergence (.ai/automation/** pipeline YAMLs, lambda handlers, scripts — consumers often prototype steps/gates/branch-pins ahead of the plugin) |
| Manual action | Issues that cannot be auto-fixed | Missing gitignore entries, missing config sections, broken branch references |
If dx-doctor reports zero issues:
✓ All checks passed. Nothing to upgrade.
STOP.
1. Present Fix Plan
Before applying any fixes, present a summary table for each category:
## Upgrade Plan
### Auto-fix (no confirmation needed)
| File | Issue | Fix |
|------|-------|-----|
| .ai/lib/audit.sh | stale | Update from plugin |
| .ai/project/component-index.md | stale | Update from plugin data |
| .github/agents/ | 4 new, 2 stale | Install new + update stale from templates |
| .github/hooks/hooks.json | 3 dx entries need a plugin root | Repair with repo-hooks-audit.sh --fix |
### Needs confirmation
| File | Issue | Action |
|------|-------|--------|
| .ai/rules/pr-answer.md | stale | Show diff, ask |
| .claude/rules/be-components.md | stale | Show diff, ask |
### Manual action required
| Issue | Suggested Fix |
|-------|--------------|
| .ai/run-context/ not in .gitignore | Add to .gitignore manually |
| Missing project seed data | Run /aem-init or /aem-refresh |
Ask: Proceed with auto-fixes? (the confirmation items will be handled one-by-one next)
If the user declines, STOP.
1b. Migrate project.yaml (if exists)
If .ai/project.yaml exists (NOT .ai/project/project.yaml):
- Read
.ai/project.yaml - Read
.ai/config.yaml - Merge fields per mapping:
type→project.type(add to project: section)role→project.role(derive from type if not set: aem-frontend→frontend, aem-fullstack→fullstack, java→backend)toolchain.*→toolchain:section (add new top-level section)build.serve→build.serve(add if not present)build.lint-js→build.lint-js(add if not present)build.lint-scss→build.lint-scss(add if not present)build.lint-fix→build.lint-fix(add if not present)component.base-class→toolchain.component-base-class- Drop: modules, source, output, component.registration
- If
repos:section exists in.ai/config.yaml:- For each repo entry, if
capabilities:exists butrole:does not:- Derive role from capabilities: if capabilities includes both fe and be → fullstack; fe only → frontend; be only → backend; neither → config
- Add
role:field, removecapabilities:
- For each repo entry, if
- Write updated
.ai/config.yaml - Rename
.ai/project.yaml→.ai/project.yaml.migrated - Report: "Migrated project.yaml fields to config.yaml. Old file renamed to project.yaml.migrated."
2. Resolve Plugin Directories
Find each plugin root directory (same method as dx-doctor):
- dx plugin: Glob for
**/skills/dx-doctor/SKILL.md, navigate up 3 levels - aem plugin: Glob for
**/skills/aem-init/SKILL.md, navigate up 3 levels - auto plugin: Glob for
**/skills/auto-init/SKILL.md, navigate up 3 levels
3. Apply Auto-fixes
These are plugin-owned files — update without asking.
3a. Utility Scripts
Discovery (mirrors dx-doctor section 1d — never hardcode the file list). Glob <dx-plugin>/data/lib/*.sh and <dx-plugin>/data/lib/*.js, excluding *.test.sh, *.test.js, and anything under <dx-plugin>/data/lib/fixtures/. The remaining files plus the always-present hook form the utility manifest:
.ai/lib/<basename>←<dx-plugin>/data/lib/<basename>(one entry per discovered file).claude/hooks/stop-guard.sh←<dx-plugin>/data/hooks/stop-guard.sh
For 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).
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.
Functional local divergence (automation bundle) — NEVER silently clobber: .ai/automation/** 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/logic/steps/structure) or merely comment / 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/name-only, or which the user explicitly confirms.
3ab. Output Templates
For each stale or missing output template in .ai/templates/:
For each subdirectory (spec/, wiki/, ado-comments/):
- Create
.ai/templates/<subdir>/if missing - For each
*.templatefile in<dx-plugin>/data/templates/<subdir>/:- Read the plugin source file, Write to
.ai/templates/<subdir>/<name>
- Read the plugin source file, Write to
These are plugin-owned format definition files — always update without asking.
3b. Universal Rules
| Installed | Plugin Source |
|---|---|
.claude/rules/reuse-first.md |
<dx-plugin>/templates/rules/universal-reuse-first.md.template |
Read template, Write to installed location.
3c. Seed Data Refresh (if .ai/project/ exists and aem.docs-repo is configured)
Seed data files in .ai/project/ are project-specific — they are NOT copied from a plugin directory. To refresh them, use /aem-refresh which pulls from the docs repo or a local path.
Report: ℹ Seed data refresh is handled by /aem-refresh, not dx-upgrade.
3c-ii. Config Migration
Check dx.version in .ai/config.yaml:
- If missing or older than current plugin version:
- Read the migration script from
<dx-plugin>/skills/dx-sync/scripts/migrate-config.sh - List pending migrations between current version and plugin version
- For each pending migration, describe what will change and apply it (auto-fix — structural migrations don't need confirmation)
- Update
dx.versionto current plugin version - Report:
✓ Config migrated from <old-version> → <new-version>
- Read the migration script from
- If already current:
✓ Config version up to date (<version>)
Migration script location: <dx-plugin>/skills/dx-sync/scripts/migrate-config.sh — this is the same script used by /dx-sync. Running /dx-upgrade on a single repo applies the same migrations that /dx-sync would apply across all consumers.
3d. AEM Rule Files (if aem plugin configured)
Use a recursive glob to find all templates: <aem-plugin>/templates/rules/**/*.md.template
For each .md.template file found:
- Strip the
.templateextension to get the destination filename - Preserve subdirectory structure under
<aem-plugin>/templates/rules/→.claude/rules/- Example:
shared/audit.md.template→.claude/rules/audit.md - Example:
shared/qa-basic-auth.md.template→.claude/rules/qa-basic-auth.md - Example:
be/be-components.md.template→.claude/rules/be-components.md - Example:
fe/fe-tokens.md.template→.claude/rules/fe-tokens.md
- Example:
- Read source, Write to destination (flattening the subdir — destination is always directly under
.claude/rules/, not in a subdir)
3d-ii. Playwright browser migration (v3.0.0+, if aem plugin configured)
Breaking change in dx-aem v3.0.0: AEM browser automation moved from chrome-devtools-mcp to @playwright/mcp (server playwright). If upgrading from a v2.x dx-aem:
- Install the Playwright browser (the server is bundled with the plugin but its Chromium is not):
Without it,npx playwright install chromium/aem-verify,/aem-qa,/aem-fe-verify, and/aem-editorial-guidefail at first navigation. - Install the auth helper if missing: copy
<aem-plugin>/data/lib/aem-playwright-auth.sh→.ai/lib/(chmod +x) and ensure.gitignorehas.ai/playwright/. - Report as manual-action:
dx-perfwas removed in v3 (no replacement yet). Any local.claude/skills/dx-perf/shadow or scripts referencing chrome-devtools tool names (mcp__plugin_dx-aem_chrome-devtools-mcp__*) must be updated tomcp__plugin_dx-aem_playwright__browser_*.
3e. Copilot Agents and Skills
If .github/agents/ exists (Copilot was enabled):
Agents: Run the agent install script:
bash <dx-plugin>/skills/dx-init/scripts/install-copilot-agents.sh --force <dx-plugin>
The --force flag overwrites stale agents with latest templates.
3e-ii. Copilot Repo Hooks (.github/hooks/)
If dx-doctor step 6.5d reported any dx: finding, repair in place:
bash <dx-plugin>/skills/dx-doctor/scripts/repo-hooks-audit.sh --fix .
What --fix changes, in every .github/hooks/*.json, and nothing else:
- 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 - replaces a stale dx branch guard (permission-rule matcher,
exit 1, nogit commitstdin filter) with the template's, matcher included - drops duplicate dx guards; adds the branch guard / agentStop guard to
hooks.jsonif missing
Hooks 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.
Report as - .github/hooks/hooks.json ← repaired (<N> dx entries) under Updated.
3f. Template-Generated Files
For missing (not stale) template-generated files:
| Missing File | Plugin Source | Action |
|---|---|---|
.ai/me.md |
— | Create with the demo template (same as dx-init step 5e) |
3g. Settings
If .claude/settings.json is missing or lacks attribution:
- If file missing: Write
{"attribution": {"commit": "", "pr": ""}} - If file exists but no attribution: Read, add
attributionkey, Write back (preserve other settings)
3g-ii. Local Secrets File
Check .claude/settings.local.json:
- If missing: Create with empty env vars (same as dx-init step 5i). Report "Created
.claude/settings.local.json". - 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 hasaem:section in config, also add:AEM_INSTANCES(with default valuelocal:http://localhost:4502:admin:admin,qa:https://qa-author.example.com:USER:PASS). Report count of new keys added (or "up to date").
3h. MCP Configuration (ADO only)
If .mcp.json org mismatch was detected:
- Read
.mcp.json, update the org in theadoserver args, Write back
If .mcp.json is missing and scm.provider is ado:
- Create with ADO MCP entry using
scm.orgfrom config
4. Handle Customized Files (needs confirmation)
For each file flagged as "needs confirmation" — these are files the user may have intentionally edited:
4a. Shared Rules (.ai/rules/*.md)
For each stale shared rule:
- Read the installed file
- Read the plugin template (
<dx-plugin>/templates/rules/<name>.md.template) - Present a summary: "This file differs from the latest plugin template."
- Ask:
- (A) Update to latest template — overwrites with plugin template
- (B) Keep current version — no changes
- (C) Show diff — display both versions, then ask A or B
If the file has AEM sections appended (for pr-review.md and pr-answer.md):
- When updating, preserve the AEM section — replace only the dx template portion (everything before the first
## AEMor## Slingheading) - Explain this to the user: "The AEM section will be preserved. Only the dx portion is being updated."
4b. AEM Convention Rules (.claude/rules/)
For each stale AEM rule found via <aem-plugin>/templates/rules/**/*.md.template (e.g., be/be-*.md.template, fe/fe-*.md.template, shared/naming.md.template, shared/accessibility.md.template):
- Read installed file (
.claude/rules/<name>.md) and corresponding template - Ask same A/B/C as above
4c. Automation Policy (if applicable)
If .ai/automation/policy/pipeline-policy.yaml is flagged:
- Read installed and plugin source
- Ask same A/B/C — this file may have user-tuned rate limits or capability gates
4d. Automation Profile Awareness
When upgrading automation files, read automationProfile from .ai/automation/infra.json (if it exists).
- Legacy profiles (
consumer,pr-only,pr-delegation): Add manual action: "Run/auto-initto migrate to per-project model." Do NOT flag missing Lambda handlers as errors — they may be intentionally absent in legacy consumer installs. DO check thatwebhooks.pr-answerentry exists in infra.json — if missing, add manual action: "Run/auto-webhooksto create repo-scoped PR Answer hook." per-projector missing profile field: Check all automation files against enabled agents in infra.json. Lambda handlers are expected if any Lambda-based agents are enabled.
4e. Webhook Migration (v2.10+)
If .ai/automation/infra.json exists and has webhooks.pr-answer WITHOUT a filter field containing repository:
- Report as manual action: "PR Answer hook may be project-scoped (legacy). Run
/auto-webhooksto create a repo-scoped hook filtered to this repo + base branch."
This applies to both hub and consumer profiles — all repos should have their own repo-scoped PR Answer hook.
5. Report Manual Actions
List all issues that cannot be auto-fixed. These require the user to take action:
### Manual Actions Required
1. **Add to .gitignore:** `.ai/run-context/`
2. **Run /aem-init:** project seed data is missing
3. **Run /auto-init:** .ai/automation/infra.json not found
4. **Verify branch:** scm.base-branch 'develop' not found in remotes — check .ai/config.yaml
5. **Check build config:** build.command uses 'mvn' but pom.xml not found
For 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).
6. Summary Report
## Upgrade Complete
| Action | Count |
|--------|-------|
| Files updated | 5 |
| Files created | 1 |
| Files skipped (kept by user) | 1 |
| Manual actions remaining | 2 |
### Updated
- .ai/lib/audit.sh ← from plugin
- .claude/hooks/stop-guard.sh ← from plugin
- .ai/project/component-index.md ← from plugin data
- .ai/project/markets.md ← from plugin data
- .claude/rules/be-components.md ← from plugin template
### Created
- .ai/me.md ← demo template
### Kept (user's version)
- .ai/rules/pr-review.md
### Manual Actions Required
1. Add `.ai/run-context/` to .gitignore
2. Verify `scm.base-branch` in .ai/config.yaml
→ Run /dx-doctor to verify
Examples
-
/dx-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). -
/dx-upgrade dx— Scopes the upgrade to only the dx-core plugin. Updatesaudit.shandstop-guard.shfrom plugin data, installs 4 new Copilot skill templates, and reports "Suggest re-run:/dx-doctorto verify." -
/dx-upgrade aem— Scopes to the dx-aem plugin. Updates stale AEM convention rules in.claude/rules/, preserves user-customizedpr-review.mdAEM section, and reports seed data refresh should be done via/aem-refresh.
Copilot CLI Plugin Update
Copilot CLI's /plugin marketplace update may fail for local marketplaces with "Failed to fetch git marketplace". To update plugins in Copilot CLI, uninstall and reinstall:
/plugin uninstall dx-core
/plugin uninstall dx-aem
/plugin install dx-core@dx-aem-flow
/plugin install dx-aem@dx-aem-flow
This picks up the latest version from the local marketplace source.
Troubleshooting
-
"All checks passed. Nothing to upgrade." Cause: All project files match the latest plugin versions. Fix: No action needed. This is the desired state after a successful upgrade.
-
Customized rule file shows unexpected diff Cause: Both the plugin template and the user have made changes to the same file. 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
.templateand manually merge. -
"Missing config section" reported as manual action Cause: A newer plugin version introduced a config section (e.g.,
aem:orautomation:) that doesn't exist in your.ai/config.yaml. Fix: Run the appropriate init skill (/aem-init,/auto-init) to interactively add the missing config section.
Rules
- Doctor first — always run dx-doctor before applying any fixes
- Confirm before overwriting customized files — auto-fix plugin-owned files; ask for user-editable files
- Never touch config values — update file structure and template content, never change user-entered config values in config.yaml
- Never touch me.md content — only create if missing (use demo template)
- Preserve AEM sections — when updating shared rules that have AEM sections appended, keep the AEM portion intact
- Preserve user data in infra.json/repos.json — never overwrite these automation config files
- Report everything — show what was changed, what was skipped, and what needs manual action
- Suggest re-run — always end with "Run
/dx-doctorto verify" - Gitignore is sacred — never auto-modify .gitignore; list needed entries as manual actions
- Template-driven — always Read source files from plugin directories; never hardcode file content
- chmod +x — always set executable permission on shell scripts after copying
04 同仓库更多 Skills
dx-hub-status
Show hub dispatch status — which repos are running, done, blocked or failed. Use for 'hub status', 'what's running'.
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".
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'.
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".
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'.
dx-ticket-analyze
Research an ADO/Jira ticket and list the source files and assets it involves. Use for 'analyze ticket', 'what files does this touch?', 'find files for this story'.