Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions plugins/aem/cloud-service/skills/migration/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ description: |
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), Guava cache → Caffeine swaps (guavaCache), and static→editable
template modernization. Also externalizes OSGi config secrets to Cloud Manager (scans
ui.config/.cfg.json for $[secret:]/$[env:] placeholders) and converts AMS/on-prem Dispatcher
configs to AEMaaCS (Branch E).
Custom Design Widgets (cdw), Guava cache → Caffeine swaps (guavaCache), 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) and
converts AMS/on-prem Dispatcher configs to AEMaaCS (Branch E).
license: Apache-2.0
---

Expand All @@ -33,6 +33,7 @@ This skill drives the **migration workflow**: BPA data, CAM/MCP, **one pattern p
| **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 |
| **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. |
Expand All @@ -45,6 +46,7 @@ This skill drives the **migration workflow**: BPA data, CAM/MCP, **one pattern p
- *"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`."*

Expand Down Expand Up @@ -116,6 +118,19 @@ If the user asks to **convert / migrate a Dispatcher configuration** to AEM as a
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.

## When to Use This Skill

- Migrate legacy AEM Java toward **Cloud Service–compatible** patterns (scheduler, ResourceChangeListener, replication, EventListener/EventHandler, AssetManager)
Expand All @@ -124,6 +139,7 @@ If the user asks to **convert / migrate a Dispatcher configuration** to AEM as a
- **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).

Branch routing and the read-first delegation for each entry above are defined once in **Required delegation** — this list is only the "when."

Expand Down Expand Up @@ -245,8 +261,9 @@ The runbook covers **every pattern the migration skill can address**. Each patte
| `lui`, `cdw`, `templateModernization` | BPA `cascade` → `content-scan` fallback | When a BPA CSV/CAM source is present, these come from BPA (subtypes `custom.classic.widget`; `legacy.dialog.classic`/`.coral2`; `legacy.static.template` + `custom.static.template`). With no BPA source, a heuristic `.content.xml` scan is the fallback — for `templateModernization` it walks `apps/<appId>/templates/**` at **any depth** (nested/grouped templates included) and classifies each static template as `custom.static.template` or `legacy.static.template` from its page-component resource type, so the custom-vs-legacy distinction survives even without a BPA report. Sample prompts route to **Branch D** (legacy-ui) / **Branch C** (templates), not code-assessment |
| `guavaCache` | `bpa-only` (no analyzer, no content-scan) | BPA is the **sole** source of truth (subtype `custom.guava.cache`), one finding per **bundle** — `identifier` on this subtype is a Guava-internal class, not a customer class, so raw rows are deduped to the bundle named in the message, not surfaced per row. With no BPA source, `guavaCache` has no deterministic fallback and surfaces under **Tier 4 — LLM scan**: the agent greps `.java` files for `import com.google.common.cache` per module, per [references/guava-cache.md](references/guava-cache.md), and tags the result `confidence: llm`. There is deliberately no compiled analyzer detector for this pattern — it does not run inside `code-assessment`'s own discovery. |
| `dispatcherConversion` | `content-scan` | Heuristic scan for an AMS / on-prem Dispatcher config layout (a monolithic `dispatcher.any` + `conf.vhost.d/`, or `conf.dispatcher.d/` AMS trees). Detected by `dispatcher-inventory.js`; the sample prompt routes to **Branch E**. |
| `oakIndex` | `bpa-only` (no analyzer, no content-scan) | BPA is the **sole** source of truth (subtypes `index.rule.violation` / `standard.index.modification`), one finding per Oak index path. With no BPA source, `oakIndex` has no deterministic fallback and surfaces under **Tier 4 — LLM scan**: the agent locates `_oak_index/*.xml` directly per [references/oak-index.md](references/oak-index.md). Sample prompt routes to **Branch F** (beta). |

`htlLint`, `osgiConfig`, and the content-scan **fallback** for `lui`/`cdw`/`templateModernization` are **heuristic** (tagged `confidence: heuristic` in the cache) — candidate matches, not compiler-validated. BPA-sourced `lui`/`cdw`/`templateModernization`/`replication`/`guavaCache` findings are authoritative. Out of scope: `inject-in-sling-model` and `outdated-dependencies` (those belong to code-assessment's own runbook, not migration).
`htlLint`, `osgiConfig`, and the content-scan **fallback** for `lui`/`cdw`/`templateModernization` are **heuristic** (tagged `confidence: heuristic` in the cache) — candidate matches, not compiler-validated. BPA-sourced `lui`/`cdw`/`templateModernization`/`replication`/`guavaCache`/`oakIndex` findings are authoritative. Out of scope: `inject-in-sling-model` and `outdated-dependencies` (those belong to code-assessment's own runbook, not migration).

**BPA is the source of truth when a report is available.** `lui`/`cdw`/`templateModernization`/`replication` are read from the BPA CSV/CAM (the parser now extracts these subtypes and excludes `_COUNT_*`/`_STAT` summary rows), so the runbook counts match your BPA report's LUI-dialog / CDW / static-template / REP tallies. `lui` keeps only the dialog sub-types (`legacy.custom.component` → create-component; `legacy.static.template` is counted under `templateModernization`). The `.content.xml` scan is only the fallback when no BPA source is present — and it can **undercount** relative to BPA when the flagged legacy nodes live in packages (e.g. acs-commons) not in the project source. `replication`: BPA `replication.agent` findings when a report is present, else the analyzer detects `Replicator` usage from source.

Expand Down Expand Up @@ -304,6 +321,8 @@ First check the non-Java branches (routed in full under **Required delegation**)

If the request is **dispatcher conversion** — convert or migrate an AMS or on-premise Dispatcher configuration to AEM as a Cloud Service — follow **Branch E**. No Java pattern module is needed. **Skip** Branch B.

If the request is **oak index migration** — fix `oakIndex` findings, or convert `_oak_index` definitions to AEM as a Cloud Service — follow **Branch F** (beta). No Java pattern module is needed. **Skip** Branch B.

Otherwise map the request to a pattern id: `scheduler`, `resourceChangeListener`, `replication`, `eventListener`, `eventHandler`, `assetApi`, `htlLint`, `lui`, `cdw`. If unclear, use **Manual Pattern Hints** in **`{code-assessment}/SKILL.md`** or ask the user to pick one of those.

### Step 2: Availability
Expand Down
Loading
Loading