migration · adobe — скилл для Claude Code: перенос AEM 6.x в AEMaaCS
Скилл для перевода легаси-проекта AEM 6.x, AMS или on-prem на AEM as a Cloud Service: сначала разбор проекта, потом починка одного блокера за сессию.
npx skills add adobe/skills --skill migration -a claude-codeЧто делает migration
Скилл работает в двух режимах. Первый — обзор: просите проверить проект на миграцию, и агент собирает read-only migration-runbook.md со всеми паттернами миграции, затронутыми файлами и примерами промптов. Правок в коде он не делает. Второй режим — точечная починка конкретного блокера Cloud Service: планировщик, ResourceChangeListener, репликация, EventListener, OSGi EventHandler, DAM AssetManager, линт data-sly-test в HTL, диалоги Classic UI / ExtJS / Coral 2 → Coral 3, Custom Design Widgets, зависимости установки Vault-пакетов, замена кеша Guava на Caffeine, разбор использования java.io.InputStream, перевод статических шаблонов в редактируемые.
Данные о находках берутся из BPA — CSV или кеша, либо через CAM и MCP. Есть и ручной путь: указать пару файлов, BPA тогда не нужен. Отдельно скилл выносит секреты из конфигов OSGi в Cloud Manager, сканируя ui.config и .cfg.json на плейсхолдеры $[secret:] и $[env:], и конвертирует конфиги Dispatcher из AMS или on-prem в формат AEMaaCS.
Главное ограничение — одна сессия, один паттерн. Попросите «починить всё» — скилл сначала заставит выбрать, планировщик или репликация. Так сделано намеренно: правила и шаги трансформации живут в другом скилле, code-assessment, и туда идёт передача после определения паттерна. Поэтому ставьте установку aem-cloud-service целиком, чтобы обе ветки были на месте.
Какие задачи решает
- оценить весь проект AEM перед переездом в Cloud Service и получить список затронутых файлов
- починить находки планировщика по выгрузке BPA в CSV
- забрать находки из CAM через MCP, выбрав нужный проект из списка
- вынести секреты из конфигов OSGi в переменные Cloud Manager
- перевести статические шаблоны в редактируемые и сгенерировать правила Modernize Tools
Примеры запросов агенту
- Проверь мой код на миграцию в AEMaaCS
- Почини находки scheduler по
./path/to/bpa.csv - Забери находки scheduler из CAM, проект выберу из списка
Как установить migration
1Через Skills CLI (Vercel)
npx skills add adobe/skills --skill migration -a claude-code2Вручную: положить файлы
~/.claude/skills/migration/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/migration/
1Через Skills CLI (Vercel)
npx skills add adobe/skills --skill migration -a codex2Вручную: положить файлы
.agents/skills/migration/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add adobe/skills --skill migration -a cursor2Вручную: положить файлы
.cursor/skills/migration/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install adobe/skills migration2Вручную: положить файлы
.github/skills/migration/SKILL.md1Через Skills CLI (Vercel)
npx skills add adobe/skills --skill migration -a gemini-cli2Командой платформы
gemini skills install https://github.com/adobe/skills --path plugins/aem/cloud-service/skills/migrationВручную: положить файлы
.devin/skills/migration/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add adobe/skills --skill migration -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Вопросы о migration
Как установить migration в Claude?
Выполните npx skills add adobe/skills --skill migration -a claude-code. После этого файл скилла лежит в ~/.claude/skills/migration/SKILL.md.
Что делает скилл migration?
Ведёт миграцию легаси-AEM на AEM as a Cloud Service: собирает отчёт по проекту в migration-runbook.md либо правит один конкретный блокер Cloud Service за сессию.
Почему скилл не берётся чинить всё сразу?
Он устроен по принципу «один паттерн за сессию»: сначала нужно выбрать, что именно чинить, например планировщик или репликацию. Правила трансформации при этом лежат в скилле code-assessment, куда идёт передача после определения паттерна.
Исходный текст
SKILL.md · Apache-2.0
---
name: migration
description: |
Migrates legacy AEM (6.x, AMS, on-prem) to AEM as a Cloud Service via BPA CSV/cache and
CAM/MCP discovery, one pattern per session. Use to review/scan a project for AEMaaCS
migration — generates a read-only migration-runbook.md — or to fix specific Cloud Service
blockers: scheduler, ResourceChangeListener, replication, EventListener, OSGi EventHandler,
DAM AssetManager, HTL data-sly-test lint, Classic UI / ExtJS / Coral 2 → Coral 3 dialog migration (lui),
Custom Design Widgets (cdw), Vault package install-time dependencies (vault-package-dependencies),
Guava cache → Caffeine swaps (guavaCache), java.io.InputStream usage triage (inputStream),
Oak index conversion (oakIndex, beta), and static→editable template modernization. Also
externalizes OSGi config secrets to Cloud Manager (scans ui.config/.cfg.json for $[secret:]/$[env:]
placeholders), converts AMS/on-prem Dispatcher configs to AEMaaCS (Branch E), and validates
migrated code on a local Cloud SDK (Branch G, beta).
license: Apache-2.0
---
# AEM as a Cloud Service — Code Migration
**Source → target:** Legacy **AEM 6.x / AMS / on-prem** → **AEM as a Cloud Service**. Scoped under `skills/aem/cloud-service/skills/migration/` so this is not confused with Edge Delivery or 6.5 LTS.
This skill drives the **migration workflow**: BPA data, CAM/MCP, **one pattern per session**, and target discovery. **Transformation rules and steps** live in the **`code-assessment`** skill — once a finding's pattern is identified, hand off to `{code-assessment}/<pattern>/SKILL.md` (or the relevant shared reference under `{code-assessment}/references/`).
**Setup:** Use the **`aem-cloud-service`** install (see repository root **README**) so both **migration** and **code-assessment** paths are available. If you already have the monorepo open with resolvable `{code-assessment}` paths, no separate install step is required.
## Quick start (for the person driving the agent)
**One pattern per chat/session** — if you ask to "fix everything," the skill will ask you to pick first (e.g. scheduler vs replication vs htlLint).
| You have… | Say something like… | What happens |
|-----------|---------------------|--------------|
| **A whole project to assess** | *"Review my code for AEMaaCS migration"* | Generates read-only `migration-runbook.md` — **all** migration patterns (Java cascade + `htlLint` + `osgiConfig`), affected files, sample prompts. **No edits.** |
| A **BPA CSV** | *"Fix **scheduler** findings using `./path/to/bpa.csv`"* | Fastest path: CSV → cached collection → files |
| **CAM + MCP** only | *"Get **scheduler** findings from CAM; I'll pick the project when you list them."* | Agent lists projects → you confirm → MCP fetch ([cam-mcp.md](references/cam-mcp.md)) |
| **Just a few files** | *"Migrate **scheduler** in `core/.../MyJob.java`"* | Manual flow: no BPA required |
| **OSGi → Cloud Manager** | *"**Scan my config files and create Cloud Manager environment secrets or variables.**"* | Agent **auto-reads** [references/osgi-cfg-json-cloud-manager.md](references/osgi-cfg-json-cloud-manager.md) (full Adobe-aligned rules inlined there); no BPA pattern id |
| **HTL lint warnings** | *"Fix **htlLint** issues in `ui.apps`"* | Proactive discovery via `rg` → fix per the HTL lint reference |
| **Vault package dependencies** | *"Fix **vault-package-dependencies** findings"* / *"Package install fails on AEMaaCS."* | Agent reads [references/vault-package-dependencies.md](references/vault-package-dependencies.md) — heuristic `pom.xml` scan (no BPA subtype, no analyzer) for `day/cq60/product:*` install-time deps in `content-package-maven-plugin`; removes the whole `<dependencies>` block. Not a `code-assessment` pattern — this dependency shape never occurs in native AEMaaCS code. |
| **Oak index findings (OID)** [BETA] | *"Fix **oakIndex** findings using `./path/to/bpa.csv`"* — covers `index.rule.violation` and `standard.index.modification` | Invokes Adobe's `@adobe/aem-cs-source-migration-index-converter` per [references/oak-index.md](references/oak-index.md); computes the next available `-custom-N` instead of assuming `-custom-1`; shows diff + type-compatibility check in IDE; validates with `mvn` and `aemanalyser`. **Branch F.** |
| **Template modernization** | *"**Migrate my static templates to editable templates and generate Modernize Tools rules.**"* / *"Create editable templates from my static templates."* / *"Generate AEM Modernize Tools structure/component/policy rules."* | Agent **auto-reads** [references/template-modernization/template-modernization-context.md](references/template-modernization/template-modernization-context.md) (shared discovery + structured context), produces a **per-template plan table**, then executes the plan using [editable-template-creation.md](references/template-modernization/editable-template-creation.md) and [aem-modernization.md](references/template-modernization/aem-modernization.md), and validates via [template-modernization-validation.md](references/template-modernization/template-modernization-validation.md). No BPA pattern id. |
| **Dialog migration** | *"Convert my Classic UI / ExtJS dialogs to Touch UI."* / *"Upgrade Coral 2 dialogs to Coral 3."* / *"Fix LUI dialog findings."* | Agent reads [references/legacy-ui/dialog/context.md](references/legacy-ui/dialog/context.md) — filters BPA LUI to dialog sub-types, converts via [extjs-to-coral3.md](references/legacy-ui/dialog/extjs-to-coral3.md) or [coral2-to-coral3.md](references/legacy-ui/dialog/coral2-to-coral3.md), validates via [validation.md](references/legacy-ui/dialog/validation.md). BPA pattern id: `lui`. |
| **Custom widget migration** | *"Fix my CDW findings."* / *"Migrate custom ExtJS widgets to Coral 3."* | Agent reads [references/legacy-ui/cdw/context.md](references/legacy-ui/cdw/context.md) — inventories xtypes, maps or scaffolds Granite UI components via [conversion.md](references/legacy-ui/cdw/conversion.md), validates via [validation.md](references/legacy-ui/cdw/validation.md). BPA pattern id: `cdw`. Run CDW before dialog migration when both are needed. |
| **Guava cache warnings** | *"Fix **guavaCache** findings using BPA CSV."* / *"Swap Guava cache for Caffeine."* | Agent reads [references/guava-cache.md](references/guava-cache.md) — BPA is the source of truth (subtype `custom.guava.cache`); one finding per **bundle**, not per Guava-internal class row. BPA pattern id: `guavaCache`. Not a `code-assessment` pattern — Guava cache usage only occurs in pre-migration code, never native AEMaaCS code. |
| **InputStream advisories** | *"Fix **inputStream** findings."* / *"Triage the `java.io.InputStream` warnings in my BPA report."* | Agent reads [references/input-stream.md](references/input-stream.md) and runs the deterministic scanner `scripts/input-stream-runner.js` (pure Node). Adobe documents the risk as binary data streamed through the JVM, fixed by direct binary upload and CDN delivery. The scanner produces one finding per file, ordered by risk, with every stream site pre-classified (F deserialization / E binary streamed or processed in the JVM / D local filesystem / C unbounded read / B unclosed stream or undisposed `Binary` / A benign) and tagged with a fix kind (`decision` / `review` / `auto`). Same precedence as the other BPA patterns: BPA findings first (CAM, then a BPA CSV, subtype `java.io.inputstream`), whose classes the scanner resolves to workspace files for line-level sites, with classes outside the workspace collapsed to one informational row per bundle (customer code kept elsewhere, platform-provided AEM Forms add-on, or third-party); the whole workspace is scanned only when BPA has no `inputStream` findings. The agent proposes tier-aware fixes for D/E/F, fixes unclosed streams, and verifies each edit with a `--files` re-scan. BPA pattern id: `inputStream`. Not a `code-assessment` pattern, since BPA only raises it for code carried over from legacy AEM. |
| **Dispatcher conversion** | *"Convert my AMS / on-prem Dispatcher config to AEM as a Cloud Service."* | Agent reads [references/dispatcher/context.md](references/dispatcher/context.md) — detects the config **mode**, generates the tool config, runs Adobe's `dispatcher-converter`, **verifies** output (filter/ACL hard-gate), and validates. **Branch E.** Runbook pattern id: `dispatcherConversion` (heuristic). |
| **Validate a migration** [BETA] | *"Validate my migration on the local Cloud SDK."* / *"Verify the scheduler fix before I raise a PR."* | Agent reads [references/validation/validate-migration.md](references/validation/validate-migration.md) — builds, deploys to the running local SDK, checks bundle/component state via the AEM Quickstart MCP, and reports the outcome to CAM when a project is linked. **Branch G.** |
**Starter prompts (copy-paste)** — the Quick start table above covers each pattern individually; these add the whole-project entry point, source-specific invocations (CSV / CAM / manual), and multi-step combinations:
- *"Review my code for AEMaaCS migration"* — **start here** for a full runbook before changing anything.
- *"Use the migration skill: **scheduler** only, BPA CSV at `./reports/bpa.csv`."*
- *"**Replication** only from CAM; list projects first, I'll pick one."*
- *"**Manual:** **event listener** migration for `.../Listener.java`."*
- *"Fix **oakIndex** findings using BPA CSV at `./reports/bpa.csv`."*
- *"Fix all Classic UI and custom widget findings — CDW first, then dialogs."*
- *"Fix **guavaCache** findings using BPA CSV at `./reports/bpa.csv`."*
- *"Fix **inputStream** findings using BPA CSV at `./reports/bpa.csv`."*
## Path convention (Adobe Skills monorepo)
From the **repository root** (parent of the `skills/` directory):
| Symbol | Path |
|--------|------|
| **`{code-assessment}`** | `skills/aem/cloud-service/skills/code-assessment/` |
Examples: `{code-assessment}/SKILL.md`, `{code-assessment}/scheduler/SKILL.md`, `{code-assessment}/references/scr-to-osgi-ds.md`.
## Workspace scope (IDE) — user code only
Applies to **finding and editing the user's AEM project** (Java, bundles, config, HTL), not to reading installed skill files under `{code-assessment}`.
- Treat the **current IDE workspace root folder(s)** (single- or multi-root) as the **only** boundary for searches, globs, `grep`, and file reads/writes for migration targets.
- **Do not** search parent directories, sibling folders on disk, `~`, other clones, or arbitrary absolute paths to "discover" sources unless the user **explicitly** names those paths or asks you to include them.
- **BPA CSV / CAM targets:** If a `filePath` or class-to-file mapping does not resolve under a workspace root, **stop** and tell the user which paths are missing — do not hunt elsewhere on the filesystem. Ask them to open the correct project in the IDE or adjust paths.
- **Manual flow:** Only migrate files the user named that live under the workspace (or paths they explicitly provided). Do not expand scope by searching outside the workspace.
## Required delegation (do this first)
**Branch A — OSGi configs → Cloud Manager** (no Java BPA pattern this session): If the user asks to **scan config files**, **create / set up Cloud Manager environment secrets or variables**, move **passwords or secrets** out of **OSGi / `.cfg.json` / `ui.config`**, or mentions **`$[secret:]`** / **`$[env:]`** for AEM CS, then **read [references/osgi-cfg-json-cloud-manager.md](references/osgi-cfg-json-cloud-manager.md) immediately** and follow the **product rules and workflow** defined in that file (Adobe AEM as a Cloud Service OSGi + Cloud Manager behavior is reproduced there—no external doc URL required). Sleek prompts are enough — **no** need to name the reference file. **Skip** branch B for that work.
**Branch B — Java / HTL / BPA pattern migration:**
1. Read **`{code-assessment}/SKILL.md`** — critical rules, Java baseline links, **Pattern Guides** table, **Manual Pattern Hints**.
2. Read the **pattern guide** (or reference) for the **single** active pattern:
- `scheduler` → **`{code-assessment}/scheduler/SKILL.md`** *(pattern guide)*
- `resourceChangeListener` → **`{code-assessment}/resource-change-listener/SKILL.md`** *(pattern guide)*
- `replication` → **`{code-assessment}/replication/SKILL.md`** *(pattern guide)*
- `eventListener` / `eventHandler` → **`{code-assessment}/event-migration/SKILL.md`** *(pattern guide — both JCR and OSGi Event Admin paths)*
- `assetApi` → **`{code-assessment}/asset-manager/SKILL.md`** *(pattern guide)*
- `htlLint` → **`{code-assessment}/references/data-sly-test-redundant-constant.md`** *(reference — HTL lint is a single shared reference, not a dedicated pattern guide)*
- `vault-package-dependencies` → **[references/vault-package-dependencies.md](references/vault-package-dependencies.md)** *(reference — heuristic pom.xml scan; lives under `migration` only, not `code-assessment`, since this dependency shape never occurs in native AEMaaCS code)*
- `guavaCache` → **[references/guava-cache.md](references/guava-cache.md)** *(reference — Guava cache → Caffeine swap; lives under `migration` only, not `code-assessment`, since Guava cache usage does not occur in native AEMaaCS code, only in code carried over from legacy AEM)*
- `inputStream` → **[references/input-stream.md](references/input-stream.md)** *(reference — `java.io.InputStream` triage and remediation for the `DG` / `java.io.inputstream` advisory; lives under `migration` only, not `code-assessment`, because BPA raises it only for code carried over from legacy AEM. Detection is the migration-local scanner `scripts/input-stream-runner.js`, not the code-assessment analyzer)*
3. When code uses SCR, `ResourceResolver`, or console logging, read **`{code-assessment}/references/scr-to-osgi-ds.md`** and **`{code-assessment}/references/resource-resolver-logging.md`** (or the hub **`{code-assessment}/references/aem-cloud-service-pattern-prerequisites.md`**).
Do not transform **Java or HTL** until the pattern guide (or reference) is read (branch B). Branch A does not require `{code-assessment}` pattern guidance.
**Branch C — Template Modernization** (no BPA): static → editable templates and/or AEM Modernize Tools rules (structure/component/policy). Three phases: context → per-template execute → validate. Start at [references/template-modernization/template-modernization-context.md](references/template-modernization/template-modernization-context.md); generators are [editable-template-creation.md](references/template-modernization/editable-template-creation.md) and [aem-modernization.md](references/template-modernization/aem-modernization.md); post-gen checks in [template-modernization-validation.md](references/template-modernization/template-modernization-validation.md). **Skip** branch B.
**Branch D — Legacy UI Migration** (`legacy-ui/` sub-folders): If the user asks to convert Classic UI / ExtJS dialogs, upgrade Coral 2 dialogs, migrate custom ExtJS widgets, fix LUI or CDW BPA findings, or mentions `cq:Dialog` / `xtype` / `cq:Widget`:
- **For dialog findings** (`lui` pattern, `legacy.dialog.classic` or `legacy.dialog.coral2` only):
1. Read [references/legacy-ui/dialog/context.md](references/legacy-ui/dialog/context.md) — `getBpaFindings('lui', …)`, filter to dialog sub-types, skip all others with a note.
2. `convert-extjs` → [references/legacy-ui/dialog/extjs-to-coral3.md](references/legacy-ui/dialog/extjs-to-coral3.md).
3. `upgrade-coral2` → [references/legacy-ui/dialog/coral2-to-coral3.md](references/legacy-ui/dialog/coral2-to-coral3.md).
4. Validate: [references/legacy-ui/dialog/validation.md](references/legacy-ui/dialog/validation.md).
- **For custom widget findings** (`cdw` pattern):
1. Read [references/legacy-ui/cdw/context.md](references/legacy-ui/cdw/context.md) — `getBpaFindings('cdw', …)`, inventory xtypes.
2. Per xtype: [references/legacy-ui/cdw/conversion.md](references/legacy-ui/cdw/conversion.md) (apply mapping or scaffold Granite UI component).
3. Validate: [references/legacy-ui/cdw/validation.md](references/legacy-ui/cdw/validation.md).
4. If the same components also have LUI `legacy.dialog.classic` findings, run dialog migration afterwards — all xtypes are now resolved.
**Run order when both are needed: CDW first, then dialog.** CDW resolves custom xtypes so dialog conversion can proceed without stops. **Skip** Branch B. **Skip** Branch C.
**Branch E — Dispatcher Conversion** (AMS / on-premise Apache `httpd` + Dispatcher → AEMaaCS; no Java BPA pattern this session):
If the user asks to **convert / migrate a Dispatcher configuration** to AEM as a Cloud Service, follow the **6-phase flow**. It wraps Adobe's maintained `@adobe/aem-cs-source-migration-dispatcher-converter` as the conversion engine and adds detection, config generation, output verification, judgment, and validation on top. Start by reading [references/dispatcher/context.md](references/dispatcher/context.md). **Skip** Branch B.
1. **Inventory** — run `scripts/dispatcher-inventory.js` (`buildInventory`) to detect the **mode** (`standard` / `flexible` / `ams` / `already-cloud` / `not-dispatcher` / `v1` / `unknown`) and count filter / rewrite / cache rules. (`ams` is a monolithic AMS on-premise config — converted via the same on-prem executor as `flexible`, just labelled honestly.) Modes and signals are defined in [references/dispatcher/context.md](references/dispatcher/context.md). If the mode is `already-cloud`, `not-dispatcher`, or `unknown`, STOP with that finding — the first two have nothing to convert, and `unknown` is an ambiguous/incomplete layout to confirm with the user before running the content-blind tool (`resolveExecutor` falls `unknown` through to the on-prem executor, so the agent is the gate here).
2. **Plan + generate `config.yaml`** — build the converter config per [references/dispatcher/config-generation.md](references/dispatcher/config-generation.md) (per-mode mapping; `variablesToReplace` is a flat mapping, `portsToMap` is a list, `appendToVhosts` is a file path).
3. **Execute** — `ensureToolInstalled` (auto-installs the Adobe tool into the gitignored `scripts/dispatcher-tool/node_modules/` on first use) then `runConverter` (`scripts/dispatcher-run.js`); the executor is selected by mode (`standard` → `main.js`, `flexible` / on-prem → `singleFileMain.js`).
4. **Verify + normalize** — run `scripts/dispatcher-verify.js` and apply [references/dispatcher/output-verification.md](references/dispatcher/output-verification.md). **HARD STOP on `filter-acl-loss`** (an empty `filters.any` when the baseline had filter rules): the conversion is not usable until it is resolved.
5. **Judgment + cross-boundary** — apply the decision catalog in [references/dispatcher/conversion-patterns.md](references/dispatcher/conversion-patterns.md); hand any Cloud Manager environment variables to **Branch A** (OSGi → Cloud Manager); flag CDN-candidate rules. Target end-state conventions are in [references/dispatcher/current-sdk-conventions.md](references/dispatcher/current-sdk-conventions.md). To operationalize this handoff, run `scripts/dispatcher-crossboundary.js` to build the Cloud Manager variable handoff artifact, then apply [references/dispatcher/cross-boundary.md](references/dispatcher/cross-boundary.md) to route each concern — CM vars → **Branch A**; immutable freshness → the `dispatcher` skill's `sdk(diff-baseline)`; security headers / edge → `security-hardening`; validation → `config-authoring`.
6. **Validate** — validate the converted `src` per [references/dispatcher/validation.md](references/dispatcher/validation.md) (delegates to the `dispatcher` skill's SDK validator + guardrails); iterate until clean. Do not present the result as done on validation failure. After validation, render the consolidated report with `scripts/dispatcher-report.js` (`renderReport` → `writeReport`) as `conversion-report.md`, which includes the coverage counts, the CM handoff, and the delegated next-checks checklist.
**Branch F — Oak Index Migration** (legacy `_oak_index/*.xml` → AEM as a Cloud Service compatible Oak index definitions; BPA pattern id `oakIndex`, category OID):
> **Beta**: Oak index migration (Branch F) is in beta and under active development. Review its output carefully — especially the type/datatype compatibility check in step 4 — before using it on production index definitions.
If the user asks to **fix Oak index findings / convert `_oak_index` definitions** to AEM as a Cloud Service, follow the **6-step flow** in [references/oak-index.md](references/oak-index.md). It wraps Adobe's maintained `@adobe/aem-cs-source-migration-index-converter` as the conversion engine and adds detection, a dynamic `-custom-N` naming override, a type-compatibility check, and validation on top. **Skip** Branch B.
1. **Detect** — locate `_oak_index/` directories; determine `aemVersion` (`63`/`64`/`65`/`Cloud_Services`) from the project's `pom.xml`.
2. **Determine next `-custom-N`** — scan for existing `<baseName>-custom-<n>` siblings already in the target state before assuming the tool's default `-custom-1`; a prior migration or a customer's own `-custom-N` index makes reusing `-custom-1` a collision, not a fresh name.
3. **Execute** — resolve the Index Converter via `npx` and invoke it per [references/oak-index.md](references/oak-index.md#step-3--invoke-index-converter).
4. **Diff + type-compatibility check** — show the converted output vs. input; verify `oak:isOakIndexDefinition`/`type` are intact and that per-property JCR value types match between legacy and converted definitions. Flag any mismatch as `needs_manual_review: datatype mismatch on <propertyName>` — do not silently apply it.
5. **Apply** (after user confirms) — copy tool output into the repo, applying the Step 2 name override if one was computed.
6. **Validate** — `mvn -pl ui.apps clean install`, then `mvn -pl all aem-analyser:project-analyse` if configured. Report PASS/FAIL with file:line evidence.
**Branch G — Validate migration** (after a migration branch, or on request; no BPA pattern this session):
> **Beta**: Validate migration (Branch G) is in beta and under active development. Treat a PASS as a strong signal, not a guarantee — review the report before raising a PR or deploying to a Cloud Manager environment.
If the user asks to **validate / verify / smoke-test** migrated code on the local Cloud SDK, read [references/validation/validate-migration.md](references/validation/validate-migration.md) and follow it. It never edits customer source; failures go back to the branch that owns the pattern. **Skip** Branch B.
## When to Use This Skill
- Migrate legacy AEM Java toward **Cloud Service–compatible** patterns (scheduler, ResourceChangeListener, replication, EventListener/EventHandler, AssetManager)
- Fix **HTL (Sightly)** lint warnings (`data-sly-test: redundant constant value comparison`)
- Fix **Vault package install-time dependencies** (`day/cq60/product:*`) blocking package installation on AEMaaCS
- Swap **Guava cache** (`com.google.common.cache.*`) for **Caffeine** (`guavaCache`)
- Triage and fix **`java.io.InputStream`** advisories (`inputStream`, BPA `DG` / `java.io.inputstream`)
- **OSGi → Cloud Manager** secret/variable externalization (Branch A), **Template Modernization** (Branch C), **Legacy UI** dialog/CDW migration (Branch D)
- Drive work from **BPA** (CSV or cached collection) or **CAM via MCP**, **one pattern per session**
- **Dispatcher Conversion:** **Branch E** — convert AMS / on-premise Apache+Dispatcher configs to AEMaaCS via Adobe's `dispatcher-converter`, with mode detection, config generation, output verification (filter/ACL hard-gate), cross-boundary handoff, and SDK validation. References: [references/dispatcher/](references/dispatcher/).
- **Oak Index Migration:** **Branch F** (beta) — convert legacy `_oak_index/*.xml` definitions via Adobe's `index-converter`, with a dynamic `-custom-N` naming override, a type/datatype compatibility check, and validation. BPA pattern id: `oakIndex`. Reference: [references/oak-index.md](references/oak-index.md).
- **Validate migrated code:** **Branch G** (beta) — build, deploy to the local Cloud SDK, and check the migration contract and bundle/component state. Reference: [references/validation/validate-migration.md](references/validation/validate-migration.md).
Branch routing and the read-first delegation for each entry above are defined once in **Required delegation** — this list is only the "when."
## Prerequisites
- Project source and Maven/Gradle build
- BPA CSV or MCP access optional but recommended
- For **htlLint**: `ui.apps` or equivalent content package with `.html` HTL templates
## BPA findings — flow
Scripts run via **`getBpaFindings`** (see **Calling the helper**); do not reimplement collection logic by hand unless the helper is unavailable.
The helper has **two independent paths**, chosen by what the caller configures:
1. **MCP configured** (`mcpFetcher` + `projectId` passed) → first call fetches all findings
from MCP and caches them to `<collectionsDir>/mcp/<projectId>/<pattern>.json`.
Every call (first and subsequent) reads from the MCP cache and returns one batch.
2. **MCP not configured, BPA CSV provided** → first call parses the CSV and writes the
unified-collection JSON to `<collectionsDir>/unified-collection.json`.
Every call reads from the CSV cache and returns one batch.
The two caches are disjoint — MCP sessions and CSV sessions never shadow each other. If
neither is configured, the helper reports `no-source` and the agent asks for one.
**Batching is mandatory on every path**: `getBpaFindings` returns a batch of 5 (`result.targets`) plus a `result.paging` envelope `{ total, returned, offset, limit, nextOffset, hasMore }`. Process one batch, report, stop, and resume only on the user's go-ahead — full rules in **Batched processing (batch size 5)** below.
**Note:** `htlLint` does **not** appear in BPA CSV — it uses proactive `rg` discovery instead. See **htlLint flow** below.
### CAM via MCP (summary)
Use **`fetch-cam-bpa-findings-by-pattern`** for code-transformer pattern flows (scheduler,
assetApi, eventListener, resourceChangeListener, eventHandler, guavaCache, inputStream, lui, cdw) and
**`fetch-cam-bpa-findings-by-importance`** when the user instead asks "what are the
critical/major/advisory/info findings?" (returns the latest BPA report's authoritative
`_COUNT_<code>` rows at one importance level, sorted by descending count). Either tool
requires **explicit user confirmation** of the project before being called — ask the user
for their CAM project name or ID; the tools resolve it internally (prefer **`projectId`**
when known). Do not pass an unconfirmed project name string. **Full tool schemas, REST notes, retries, and error handling:**
[references/cam-mcp.md](references/cam-mcp.md).
### Calling the helper
Scripts live under **`./scripts/`** (next to this `SKILL.md`).
```javascript
const { getBpaFindings } = require('./scripts/bpa-findings-helper.js');
// First batch (defaults: limit=5, offset=0)
const result = await getBpaFindings(pattern, {
bpaFilePath: './cleaned_file6.csv',
collectionsDir: './unified-collections',
projectId: '...',
mcpFetcher: mcpFunction
// limit: 5, // implicit default
// offset: 0, // implicit default
});
// Next batch — only after the user says to continue
if (result.paging?.hasMore) {
const next = await getBpaFindings(pattern, {
bpaFilePath: './cleaned_file6.csv',
collectionsDir: './unified-collections',
projectId: '...',
mcpFetcher: mcpFunction,
offset: result.paging.nextOffset
});
}
```
**`result`:**
- `success`, `source` (`'unified-collection' | 'bpa-file' | 'mcp-server' | …`)
- `message` (includes a human-readable batch status)
- `targets` — the **current batch** (length `<= limit`)
- `paging: { total, returned, offset, limit, nextOffset, hasMore }` — always present on
successful calls
To disable batching for a one-off programmatic caller, pass `limit: null`. The
skill workflow itself **never** does this.
### Collection caching
Collections live under **`./unified-collections/`**. If a collection exists and the user supplies a **new** CSV, ask whether to reuse or re-process. A collection written before the requested pattern was supported is rebuilt from the CSV automatically (the parser records the subtypes it extracts in `meta.parsedSubtypes`); without a CSV, a request for that one pattern returns an error rather than reporting it absent, while `all` still returns the patterns the collection covers and names the ones it can't answer (`staleCache.missingPatterns`).
### Reading a BPA CSV
Filter rows where **`pattern`** matches the session pattern. Typical columns: `pattern`, `filePath`, `message`.
### MCP errors and fallback
**Critical:** On MCP failure, **stop the workflow immediately** and give the user the **exact tool error message** (verbatim), including "not found" / 404-style project errors. **Do not** continue with migration steps, infer a different CAM project from the workspace, or switch to manual/local migration on your own.
**Exception:** enablement restriction errors (prefix documented in [references/cam-mcp.md](references/cam-mcp.md)) must be shown **verbatim** with no paraphrase and no automatic fallback until the user addresses them.
After stopping, you may summarize what failed in plain language and, if helpful, re-show projects from **`list-projects`**. **Only** continue when the user **explicitly** directs the next step (e.g. correct project id/name from the list, BPA CSV path, or specific Java files for manual flow).
For retries, error categories, and when user-directed CSV/manual paths are allowed, follow [references/cam-mcp.md](references/cam-mcp.md); still **no silent fallback**. Never hide tool errors from the user.
**Optional prompt after stop (user mu...
© adobe · Apache-2.0 · adobe/skills
Похожие скиллы
Всё по теме «DevOps и инфраструктура» →Сначала — migration от других авторов.