Skip to main content

axon4to5-migrate-code

Migrate Axon Framework 4 project code and configuration to Axon(iq) Framework 5. Migrates source code and wiring only — NOT stored data (event store contents / stored events, tracking tokens), which are left untouched.

Ir para a instalação

Informações da origem

Repositório
AxonIQ/agent-skills
Última atividade na origem
25 de julho de 2026 às 16:07
Idioma detectado do SKILL.md
inglês
Estrelas
2
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
86 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
axon4to5-migrate-code
description
Migrate Axon Framework 4 project code and configuration to Axon(iq) Framework 5. Migrates source code and wiring only — NOT stored data (event store contents / stored events, tracking tokens), which are left untouched.
argument-hint
framework=<axon|axoniq> configuration=<native|spring> mode=<single|project> [execution=<inline|subagent>] [source=<class|file|fqn>] [max-subagents=<0..N>] [auto=<true|false>]
disable-model-invocation
true
# axon4to5-migrate-code ## Goal > Fully (or as most as possible) compiling, green-test codebase on AF5, **same architecture as AF4**. > No DCB. No new patterns. Legacy event storage preserved. > > **Scope: code and configuration only.** This skill migrates source code and wiring. It does **NOT** > migrate stored data — the event store contents (stored events) and tracking tokens are left untouched. > Migrating to AF5 with the legacy event-storage layout keeps those stores compatible as-is; moving data > to a new storage layout (e.g. DCB) is out of scope. > The migration preserves the project's existing configuration style: a Spring Boot > project stays on Spring auto-config (recipes use `@Component` / `@Bean` > idioms); a plain framework-configuration project stays on the direct > `Configurer` API (recipes use `EventSourcingConfigurer` / > `MessagingConfigurer` / `CommandHandlingModule` / `EventSourcedEntityModule`). ## Available recipes (auto-listed) Run `bash scripts/list-recipes.sh` from the skill root directory. Output format: ``` - file: references/recipes/<dir>/RECIPE.md id: <id> title: <title> description: <description> applicable: | <applicable section content, or "(none)" if missing> ``` ## Inputs - `framework` (**required**): which Axon flavor to migrate. Currently supported values: `axon`, `axoniq`. Any other value → STOP. - `configuration` (**required**): how the application wires Axon. Currently supported values: `native`, `spring`. Any other value → STOP. - `mode` (required): what gets migrated in one invocation. - `single` — one element (a class, e.g. an Aggregate). Requires `source`. - `project` — the whole application (default: current working directory). `source` ignored. - `execution` (optional, default `inline`): how the orchestrator runs its steps. Only meaningful for `mode=project` — for `mode=single` it has no observable effect. - `inline` — main session does discovery + recipe runs sequentially. No `Agent` tool use. - `subagent` — orchestrator MAY dispatch via the `Agent` tool: discovery → `Explore` subagent, recipe sub-flow per item → `general-purpose` subagent (parallel batches). Useful for `project` mode on large codebases. - `source` (required for `mode=single`): hint identifying the thing to migrate (class name, file path, FQN). - `skip-openrewrite` (optional, default `false`): when `true`, the orchestrator SKIPS Pre-step 2 (the OpenRewrite bulk pass) and goes straight to the mode-specific producer. Use this when (a) OpenRewrite Phase 1 has already been run separately on the tree, (b) the caller is exercising a recipe in isolation, or (c) the project is not built with Maven/Gradle so the OpenRewrite plugin is unreachable. Values: `true` / `false`. Any other value → STOP. The downstream recipe must still tolerate both AF4-shaped and partially-migrated sources (see each recipe's `# Applicable` predicates). - `max-subagents` (optional, default `0`): max parallel `general-purpose` subagents for item processing in the drain loop. `mode=project` only — ignored for `mode=single`. `0` = inline (no subagents, sequential). `N > 0` = dispatch up to N items simultaneously as subagents; **BLOCKER_RESOLUTION always runs in main session** regardless of this value. Any non-integer or value < 0 → STOP. - `auto` (optional, default `false`): when `true`, never calls `AskUserQuestion` — all interactive decisions resolved automatically (see `## Auto mode`). Values: `true` / `false`. Any other value → STOP. ## Auto mode (`auto=true`) Orchestrator makes all decisions without `AskUserQuestion`. Every auto-resolved choice emits `⚙️ auto: <decision>` so the log stays auditable. | Decision point | Auto action | |---|---| | Ambiguous recipe match (`mode=single`) | Pick first candidate by `applicable` score. | | Blocker | Auto-select the Option the recipe marked `(Recommended)`; if none is marked, `skip`. A recommended migration path (e.g. saga `stateful-rewrite`) re-enters the recipe with that option id; `skip`/`revert` resolve in-place. See `BLOCKER_RESOLUTION.md § Auto mode`. | | Resume + selection-args mismatch | Args identical → auto-resume. Args differ → auto-start-over. | | Working tree mismatch on resume | Proceed; record `⚠️ auto: tree mismatch ignored` in `progress.md`. | | OpenRewrite step completes | Immediately continue to mode-specific producer. Do NOT pause or end session. | ## Durability **Load order — see § Recipe sub-flow.** FLOW.md first, then DURABILITY.md (second). Defines state files under `.axon4to5-migration/`, hooks across pre-steps + queue + recipe results + caller decisions, and commit protocol. Reads `progress.md` on entry to decide resume vs fresh. ## Pre-steps (common to every mode) These run **before** any mode-specific logic — independent of whether `mode=single`, `project`, or anything added later. 1. **Parse** — read `framework`, `configuration`, `mode`, `execution`, `skip-openrewrite`, `max-subagents`, `auto` from `$ARGUMENTS`. - If `framework` is missing or ∉ {`axon`, `axoniq`} → STOP and report unsupported framework. - If `configuration` is missing or ∉ {`native`, `spring`} → STOP and report unsupported configuration. - If `mode` is missing or ∉ {`single`, `project`} → STOP and report unsupported mode. - `execution` defaults to `inline` if missing. If present and ∉ {`inline`, `subagent`} → STOP and report unsupported execution. - `skip-openrewrite` defaults to `false` if missing. If present and ∉ {`true`, `false`} → STOP and report unsupported value. - `max-subagents` defaults to `0` if missing. If present and not a non-negative integer → STOP. - `auto` defaults to `false` if missing. If present and ∉ {`true`, `false`} → STOP. 2. **OpenRewrite** — **skipped entirely when `skip-openrewrite=true`.** Otherwise, internally invoke `axon4to5-openrewrite` via the `Skill` tool, passing `--framework $framework --commit false`. Do NOT pass `--commit true` or omit `--commit`; DURABILITY's `on:openrewrite-done` hook owns the single combined commit. This is a step of this orchestrator, not a separate command. Idempotent — safe even on a partially-migrated tree. If it fails → STOP and report the failure (no gap-filling on a broken bulk pass). When skipped, surface that fact in the eventual report (Notes or Learnings) so the caller knows the queue ran against unprocessed AF4 (or already-partially-migrated) sources and the recipes did all the work themselves. **`auto=true`: after this step returns (success or skip), immediately continue to the mode-specific producer — do NOT end the session or pause.** Only after pre-steps complete does the mode-specific producer below run. ## Modes ### `single` Migrate ONE element (one aggregate, one event processor, etc.) using exactly one recipe from the list above. Steps (after the common pre-steps): 1. **Match** — map user's request + `source` to ONE recipe in the auto-listed set. Primary signal: the catalog's `applicable` block (surface predicates against `$SOURCE` — annotations / type markers). Fallback signal: `id` + `title` + `description`. If ambiguous → ask user via `AskUserQuestion` to pick (show `title` to the user; dispatch by `id`). If no `applicable` block matches and description is also unclear → STOP and report. 2. **Execute** — `Read` the chosen recipe file under [`references/recipes/`](references/recipes/) (`<name>/RECIPE.md`) and execute it per the **Recipe sub-flow** ([`FLOW.md`](references/recipes/FLOW.md), already loaded). Recipe-local auxiliary files (examples, fixtures, supporting docs) live alongside it in the same `<name>/` directory. 3. **Verify** — behavior is preserved (no DCB, keep `AggregateBasedEventStorageEngine`, etc.). 4. **Report** — render the report (see Queue flow § Render report). MUST NOT: - Run without all required parameters resolved to a supported value. - Run multiple recipes in one invocation. - Migrate more than the single source named by the user. - Migrate anything outside the supported `(framework, configuration)` matrix — the rest of the codebase stays untouched. - Introduce DCB or swap event storage engine. ### `project` Migrate **everything in the working directory** that any recipe in the catalog declares applicable. `source` is ignored. Steps (after the common pre-steps): **Recipe loop** — iterate recipes in discovery order. For each recipe: 1. **Discover** — evaluate the recipe's `applicable` predicates across the codebase to produce candidate sources. - `execution=inline` → orchestrator scans inline using `Grep` / `Glob` / `Read`. - `execution=subagent` → dispatch one `Explore` subagent for this recipe. Read-only — no edits. - **Scan `.java` AND `.kt`, across all source roots.** JVM projects are mixed and Kotlin files often sit under `src/main/java/` (and vice-versa) — never filter candidates by extension or source directory. Key on the recipe's Axon annotations, not on path. See `DEFAULT.md § Source file conventions` (the `Explore` subagent must be told this too). 2. **Enqueue** — add `(recipe, source)` candidates. Deduplication is recipe's concern. 3. **Drain** — exhaust all pending items for **this recipe** before advancing to the next: - `max-subagents=0` (default) → inline, main session, sequentially. - `max-subagents=N` → main session acts as **coordinator**. Dispatches up to N pending items simultaneously as `general-purpose` subagents (single `Agent` message per batch). Each subagent executes ONE recipe sub-flow and returns a result block (`RESULT:` line + Notes + a `Learnings` field — complete authored entries, or an explicit `none — <why>`). The subagent **authors** the learning prose (it witnessed the run) but MUST NOT write `learnings.md` itself — the coordinator is the single safe writer under parallelism and stamps the date + commit sha, relaying each entry verbatim (see DURABILITY § Proactive Learnings). - ✅ Success / ⏭ Rejected / ❌ Failure → main records result, immediately dispatches next pending item. **No pause.** - 🚧 Blocker → **BLOCKER_RESOLUTION in main session**: `AskUserQuestion` if `auto=false`; auto-skip if `auto=true`. Resolved → re-dispatch same item to a new subagent. Not resolved → mark blocked, dispatch next pending item. - Main session never pauses unless waiting for user input on a blocker (`auto=false`). - **Fallback** — if a subagent cannot be spawned, process inline and continue. 4. **Mark recipe done** — `on:recipe-done` hook records status in `progress.md` Recipe status table. After all recipes drained → **Debugging loop** → **Finalize** → **Report**. **Context hygiene** — after every 5 items drained, emit this tip once (then reset counter): > 💡 Context is growing. Run `/clear` and re-invoke the skill — it resumes automatically from `.axon4to5-migration/progress.md`, no work is lost. MUST NOT: - Spawn a subagent under `execution=inline`. - Pass anything beyond `(recipe path, source, framework, configuration)` to a recipe subagent — context bloat defeats the parallelism win. - Cross repository boundaries during discovery. - Halt the queue on a single Failure — record and drain the rest. - Introduce DCB or swap event storage engine. ## Queue flow `$SOURCE` is referenced throughout the recipe sub-flow as the argument passed to the skill from `source`. > `[[Execute recipe sub-flow]]` = [`references/recipes/FLOW.md`](references/recipes/FLOW.md), loaded at skill start. `[[Resolve blocker]]` = [`references/recipes/BLOCKER_RESOLUTION.md`](references/recipes/BLOCKER_RESOLUTION.md), budget = 1 attempt per item; on exhaustion item is marked blocked and drain continues. ### Single mode flow ```mermaid flowchart TD A[Skill invoked] --> PARSE["<b>Parse</b><br/>framework, configuration, source"] PARSE --> ORW[["<b>OpenRewrite</b><br/>(internal Skill, idempotent)"]] ORW -- fail --> XORW[STOP: bulk-rewrite failed] ORW -- ok --> B["list-recipes (catalog)"] B --> MATCH{"<b>Match</b><br/>request + source → recipe"} MATCH -- ambiguous --> ASK["AskUserQuestion<br/>(show titles, dispatch by id)"] ASK --> EXEC MATCH -- "no match" --> XNOMATCH[STOP: no applicable recipe] MATCH -- matched --> EXEC[["<b>Execute</b> recipe sub-flow<br/>(FLOW.md)"]] EXEC --> R{<b>RESULT?</b>} R -- "Blocker (first attempt)" --> BR[["<b>Resolve blocker</b><br/>(BLOCKER_RESOLUTION.md)"]] BR --> BRQ{"Resolved?<br/>budget = 1"} BRQ -- yes --> EXEC BRQ -- "no / exhausted" --> BLK["mark blocked<br/>(🚧 caller must resolve)"] R -- "Blocker (already retried)" --> BLK R -- "Success / Rejected / Failure" --> VER["<b>Verify</b><br/>behavior preserved<br/>same architecture as AF4"] VER --> RPT["<b>Report</b> &amp; END"] BLK --> RPT ``` ### Project mode flow ```mermaid flowchart TD A[Skill invoked] --> PARSE["<b>Parse</b><br/>framework, configuration, execution"] PARSE --> ORW[["<b>OpenRewrite</b><br/>(internal Skill, idempotent)"]] ORW -- fail --> XORW[STOP: bulk-rewrite failed] ORW -- ok --> B["list-recipes (catalog)"] B --> RL{"<b>Next recipe</b><br/>in order?"} RL -- "yes: &lt;recipe&gt;" --> DISC["<b>Discover</b><br/>execution=inline: Grep/Glob<br/>execution=subagent: 1 Explore<br/>→ <b>Enqueue</b> items"] DISC --> Q[(Recipe queue)] Q --> L{"<b>Drain</b><br/>pending?"} L -- yes --> INP["pick next → in-progress"] INP --> W[["<b>Execute</b> recipe sub-flow<br/>execution=inline: main session<br/>execution=subagent: general-purpose (parallel batch)"]] W --> R{<b>RESULT?</b>} R -- "Blocker (first attempt)" --> BR[["<b>Resolve blocker</b><br/>(BLOCKER_RESOLUTION.md)"]] BR --> BRQ{"Resolved?<br/>budget = 1"} BRQ -- yes --> W BRQ -- "no / exhausted" --> BLK["mark blocked<br/>(🚧 caller must resolve)"] R -- "Blocker (already retried)" --> BLK R -- "Success / Rejected / Failure" --> VER["<b>Verify</b><br/>behavior preserved<br/>same architecture as AF4"] VER --> DONE["mark done in queue"] DONE --> Q BLK --> Q L -- "no (recipe drained)" --> RDONE["<b>on:recipe-done</b><br/>update Recipe status table"] RDONE --> RL RL -- "no more recipes" --> DBG_COMP
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub