# Migrate Widgets

> Generates C# IWidgetMigration and IWidgetPropertyMigration extension code for custom widget and section type transformations (rename, restructure, consolidate, property conversion) during KX13→XbyK migration. Use when the user needs to change widget types, restructure widget data, or convert section types.

- **Type:** Skill
- **Install:** `agentstack add skill-kentico-xperience-by-kentico-kenticopilot-migrate-widgets`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Kentico](https://agentstack.voostack.com/s/kentico)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Kentico](https://github.com/Kentico)
- **Source:** https://github.com/Kentico/xperience-by-kentico-kenticopilot/tree/main/plugins/kx13-content-migration/skills/migrate-widgets

## Install

```sh
agentstack add skill-kentico-xperience-by-kentico-kenticopilot-migrate-widgets
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Widget Transformation Code Generation

Produces ready-to-use C# code files for the Migration.Tool.Extensions project. Takes the migration plan output from the migrate-plan skill — or a direct text description — as input.

## Workflow

### Step 1: Read Reference Materials

- Read [widget-migration-api.md](references/widget-migration-api.md) for the complete API patterns, annotated code samples, and decision guides.
- If you need pattern examples for implementation, read [WIDGET_MIGRATION_EXAMPLE.cs](assets/WIDGET_MIGRATION_EXAMPLE.cs) for a complete annotated reference implementation showing all patterns.
- If you need context on the migration tool's extension points or configuration, read [migration-tool.md](../_shared/references/migration-tool.md).
- If you need documentation links for further research, read [migration-docs.md](../_shared/references/migration-docs.md).
- If a Kentico documentation lookup tool is available, use it for additional context on widget migration APIs, Page Builder JSON structure, or advanced patterns like content item creation during migration.

### Step 2: Analyze Input

- If a migration plan file path is provided → read it and extract from the **Widget Transformations** section: **Section Type Mappings**, **Custom Widget Type Mappings**, **Widget Restructuring**, and **Widget Property Transforms** tables. Also check the **Code Extensions to Implement** table for rows where Type = `IWidgetMigration` or `IWidgetPropertyMigration`.
- If a direct text description is provided → identify source widget/section identifiers, target identifiers, property mappings, and transformation needs.
- Ask clarifying questions if the target widget types, property mappings, or value transformation logic are ambiguous.

### Step 3: Identify Code Units to Generate

Determine the set of classes needed:

- One `IWidgetMigration` class per source widget or section type (or per consolidation group when multiple source types map to one target).
- One `IWidgetPropertyMigration` class per distinct property transformation pattern that is reusable across widgets or needs to be delegated via the `propertyMigrations` dictionary.
- One `ServiceCollectionExtensions` class (or addition to existing) for DI registration.
- **Skip** code generation for:
  - Built-in widgets with direct XbyK equivalents (`Kentico.Widget.RichText`, `Kentico.FormWidget`) — these migrate automatically.
  - Widgets that are unchanged (same identifier and properties in XbyK) **AND** have no properties requiring `IWidgetPropertyMigration` transforms.
  - Widgets explicitly excluded in the migration plan.
- **Always generate an `IWidgetMigration`** for any widget that needs property transforms via `IWidgetPropertyMigration` — even if the widget identifier is unchanged. The migration tool only invokes standalone `IWidgetPropertyMigration` classes when API Discovery provides `EditingFormControlModel` metadata for the property. If a KX13 widget property lacks an `[EditingComponent(...)]` attribute, `EditingFormControlModel` is null and the property migration is silently skipped. An `IWidgetMigration` that delegates properties via the `propertyMigrations` dictionary uses a separate code path (`explicitMigrations`) that does not depend on API Discovery.
- **Recommend inline conversion** in `MigrateWidget` when the property transformation is simple and specific to one widget (e.g., int→string ratio). Only create a separate `IWidgetPropertyMigration` when the transformation is reusable or needs to be delegated.
- **Consider built-in property migrations first:** `WidgetFileMigration` (media files, Rank 100,000), `WidgetPathSelectorMigration` (path selectors, Rank 100,001), and `WidgetPageSelectorMigration` (page selectors, Rank 100,002) handle common conversions automatically. Only create a custom `IWidgetPropertyMigration` to **override** a built-in when the default conversion target is wrong (e.g., page selector → `ContentItemReference` instead of `WebPageRelatedItem`).

### Step 4: Generate Widget Migration Code

For each migration, generate a class implementing `IWidgetMigration`:

- `Rank` — use values ()` for each widget migration (**NOT AddSingleton**).
- `AddTransient()` for each property migration (**NOT AddSingleton**).
- Include comment noting that built-in widgets (`Kentico.Widget.RichText`, `Kentico.FormWidget`) do not need custom code.
- Include comment noting the `QuerySourceInstanceApi` appsettings prerequisite.

### Step 6: Build Verification

1. Build the `Migration.Tool.Extensions` project to verify the generated code compiles without errors.
2. If the build fails, analyze the error messages, fix all issues in the generated code, and rebuild.
3. Repeat up to 3 attempts. If the build still fails after 3 attempts, present the full build output and error details to the user for manual resolution.

#### 6b. Verify Registration Completeness

After a successful build, verify all generated migrations are properly registered:

1. Read the `ServiceCollectionExtensions` class and confirm every `IWidgetMigration` has a corresponding `AddTransient()` call (**NOT `AddSingleton`** — widget migrations are not safe as singletons).
2. Read the `ServiceCollectionExtensions` class and confirm every `IWidgetPropertyMigration` has a corresponding `AddTransient()` call.
3. Cross-reference against the migration plan's "Widget Transformations" section and "Code Extensions to Implement" table — every widget type listed with a custom mapping must have a generated file and a registration.
4. If any migration is missing registration or uses `AddSingleton` instead of `AddTransient`, fix and rebuild.

### Step 7: Present and Refine

- Save files to the user-specified path (default: `Migration.Tool.Extensions/WidgetMigrations/` — generated code belongs in the `Migration.Tool.Extensions` project, matching the `Migration.Tool.Extensions.WidgetMigrations` namespace).
- Provide a summary table using this format:

  | File                            | Pattern          | Rank | Handles                                                                    |
  | ------------------------------- | ---------------- | ---- | -------------------------------------------------------------------------- |
  | `HeroContentWidgetMigration.cs` | IWidgetMigration | 1    | Maps `Acme.HeroWidget` → `Acme.HeroBanner`, creates content item for image |

- Ask if any migrations need adjustment and iterate on feedback.

## Rules

- Follow exact API patterns from `widget-migration-api.md` — do not invent methods or types that don't exist.
- Handle both structured (migration plan) and free-text input.
- Widget JSON access pattern: `value["type"]` for the type identifier, `((JArray)value["variants"]!)[0]["properties"]` for the property bag.
- Reference built-in `WidgetFileMigration` (media files) and `WidgetPageSelectorMigration` (page selectors) in the `propertyMigrations` dictionary rather than reimplementing conversion logic.
- Namespace: `Migration.Tool.Extensions.WidgetMigrations` (user can override).
- File naming convention: `{TargetWidgetName}WidgetMigration.cs` for widget migrations, `{Concern}PropertyMigration.cs` for property migrations.
- Use string constants for source/target identifiers, following the `Source_`/`Target_` prefix convention from the example.
- Add `TODO` comments for values unknown at generation time (e.g., media GUID lookups, resource key resolution dictionaries, content item GUIDs).
- If a Kentico documentation lookup tool is available, verify uncertain API details before generating code.
- When overriding a built-in property migration, use `Rank < 100,000` to take priority over the built-in (100,000+). The `ShallMigrate` of the custom migration should match the same `FormComponentIdentifier` (via `Kx13FormComponents` constants) as the built-in it replaces.
- This skill generates `IWidgetMigration` and `IWidgetPropertyMigration` code only — `IClassMapping`, `IFieldMigration`, `ContentItemDirectorBase`, and appsettings configuration are separate extension points covered by other skills.

## Gotchas

- Use `AddTransient` for DI registration — **never `AddSingleton`**. Widget migrations are not safe to reuse as singletons.
- `ShallMigrate` must use `StringComparison.InvariantCultureIgnoreCase` — widget type identifiers are case-insensitive.
- Never write custom code for built-in widgets (`Kentico.Widget.RichText`, `Kentico.FormWidget`) — they migrate automatically.
- Check built-in property migrations (`WidgetFileMigration`, `WidgetPathSelectorMigration`, `WidgetPageSelectorMigration`) before writing custom `IWidgetPropertyMigration` classes — only override when the default conversion target is wrong.
- Section types use the same `IWidgetMigration` interface as widgets — there is no separate section migration interface.
- **`WidgetPropertyMigrationContext` only has `SiteId` and `EditingFormControlModel`** — there is no `ComponentIdentifier` property. Do not try to filter by widget type in `IWidgetPropertyMigration.ShallMigrate`. If you need widget-type-scoped property transforms, do them inline in the `IWidgetMigration.MigrateWidget` method or delegate via the `propertyMigrations` dictionary (which is already widget-scoped).
- **Standalone `IWidgetPropertyMigration` requires API Discovery** — the migration tool's `VisualBuilderPatcher` only calls `GetWidgetPropertyMigration` (rank-based lookup) when the property has a non-null `EditingFormControlModel` from API Discovery. KX13 widget properties without `[EditingComponent(...)]` attributes produce null `EditingFormControlModel`, silently skipping all property migrations. Always pair standalone `IWidgetPropertyMigration` classes with an `IWidgetMigration` that explicitly delegates via `propertyMigrations` to guarantee execution regardless of API Discovery metadata.
- **Extension methods must be in separate `static` classes** — migration classes that use primary constructors (for DI injection of `ILogger`, `ModelFacade`, etc.) are non-static. C# requires extension methods to be defined in non-generic `static` classes. Place the `Add{MigrationName}` extension method in a companion `static class {MigrationName}Extensions` in the same file.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Kentico](https://github.com/Kentico)
- **Source:** [Kentico/xperience-by-kentico-kenticopilot](https://github.com/Kentico/xperience-by-kentico-kenticopilot)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-kentico-xperience-by-kentico-kenticopilot-migrate-widgets
- Seller: https://agentstack.voostack.com/s/kentico
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
