Install
$ agentstack add skill-kentico-xperience-by-kentico-kenticopilot-migrate-widgets ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →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 [WIDGETMIGRATIONEXAMPLE.cs](assets/WIDGETMIGRATIONEXAMPLE.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 =
IWidgetMigrationorIWidgetPropertyMigration. - 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
IWidgetMigrationclass per source widget or section type (or per consolidation group when multiple source types map to one target). - One
IWidgetPropertyMigrationclass per distinct property transformation pattern that is reusable across widgets or needs to be delegated via thepropertyMigrationsdictionary. - One
ServiceCollectionExtensionsclass (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
IWidgetPropertyMigrationtransforms. - Widgets explicitly excluded in the migration plan.
- Always generate an
IWidgetMigrationfor any widget that needs property transforms viaIWidgetPropertyMigration— even if the widget identifier is unchanged. The migration tool only invokes standaloneIWidgetPropertyMigrationclasses when API Discovery providesEditingFormControlModelmetadata for the property. If a KX13 widget property lacks an[EditingComponent(...)]attribute,EditingFormControlModelis null and the property migration is silently skipped. AnIWidgetMigrationthat delegates properties via thepropertyMigrationsdictionary uses a separate code path (explicitMigrations) that does not depend on API Discovery. - Recommend inline conversion in
MigrateWidgetwhen the property transformation is simple and specific to one widget (e.g., int→string ratio). Only create a separateIWidgetPropertyMigrationwhen 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), andWidgetPageSelectorMigration(page selectors, Rank 100,002) handle common conversions automatically. Only create a customIWidgetPropertyMigrationto override a built-in when the default conversion target is wrong (e.g., page selector →ContentItemReferenceinstead ofWebPageRelatedItem).
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
QuerySourceInstanceApiappsettings prerequisite.
Step 6: Build Verification
- Build the
Migration.Tool.Extensionsproject to verify the generated code compiles without errors. - If the build fails, analyze the error messages, fix all issues in the generated code, and rebuild.
- 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:
- Read the
ServiceCollectionExtensionsclass and confirm everyIWidgetMigrationhas a correspondingAddTransient()call (NOTAddSingleton— widget migrations are not safe as singletons). - Read the
ServiceCollectionExtensionsclass and confirm everyIWidgetPropertyMigrationhas a correspondingAddTransient()call. - 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.
- If any migration is missing registration or uses
AddSingletoninstead ofAddTransient, fix and rebuild.
Step 7: Present and Refine
- Save files to the user-specified path (default:
Migration.Tool.Extensions/WidgetMigrations/— generated code belongs in theMigration.Tool.Extensionsproject, matching theMigration.Tool.Extensions.WidgetMigrationsnamespace). - 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) andWidgetPageSelectorMigration(page selectors) in thepropertyMigrationsdictionary rather than reimplementing conversion logic. - Namespace:
Migration.Tool.Extensions.WidgetMigrations(user can override). - File naming convention:
{TargetWidgetName}WidgetMigration.csfor widget migrations,{Concern}PropertyMigration.csfor property migrations. - Use string constants for source/target identifiers, following the
Source_/Target_prefix convention from the example. - Add
TODOcomments 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,000to take priority over the built-in (100,000+). TheShallMigrateof the custom migration should match the sameFormComponentIdentifier(viaKx13FormComponentsconstants) as the built-in it replaces. - This skill generates
IWidgetMigrationandIWidgetPropertyMigrationcode only —IClassMapping,IFieldMigration,ContentItemDirectorBase, and appsettings configuration are separate extension points covered by other skills.
Gotchas
- Use
AddTransientfor DI registration — neverAddSingleton. Widget migrations are not safe to reuse as singletons. ShallMigratemust useStringComparison.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 customIWidgetPropertyMigrationclasses — only override when the default conversion target is wrong. - Section types use the same
IWidgetMigrationinterface as widgets — there is no separate section migration interface. WidgetPropertyMigrationContextonly hasSiteIdandEditingFormControlModel— there is noComponentIdentifierproperty. Do not try to filter by widget type inIWidgetPropertyMigration.ShallMigrate. If you need widget-type-scoped property transforms, do them inline in theIWidgetMigration.MigrateWidgetmethod or delegate via thepropertyMigrationsdictionary (which is already widget-scoped).- Standalone
IWidgetPropertyMigrationrequires API Discovery — the migration tool'sVisualBuilderPatcheronly callsGetWidgetPropertyMigration(rank-based lookup) when the property has a non-nullEditingFormControlModelfrom API Discovery. KX13 widget properties without[EditingComponent(...)]attributes produce nullEditingFormControlModel, silently skipping all property migrations. Always pair standaloneIWidgetPropertyMigrationclasses with anIWidgetMigrationthat explicitly delegates viapropertyMigrationsto guarantee execution regardless of API Discovery metadata. - Extension methods must be in separate
staticclasses — migration classes that use primary constructors (for DI injection ofILogger,ModelFacade, etc.) are non-static. C# requires extension methods to be defined in non-genericstaticclasses. Place theAdd{MigrationName}extension method in a companionstatic class {MigrationName}Extensionsin 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
- Source: Kentico/xperience-by-kentico-kenticopilot
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.