MCPInstall

enonic-content-migration

Generates Enonic XP scripts for bulk content operations — creating, updating, querying, migrating, and transforming content using lib-content and lib-node APIs. Covers the query DSL (NoQL), aggregations, batch processing, task controllers for long-running operations, and export/import workflows. Use when writing bulk content creation, update, or deletion scripts, querying with NoQL syntax, migrating content between environments, running long-running task operations, or working with aggregations and paginated retrieval. Do not use for Guillotine GraphQL frontend queries, content type schema definitions, single contentLib.get() calls, or non-Enonic data migration tools.

Installs
143
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/webmaxru/enonic-agent-skills --skill enonic-content-migration
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads enonic-content-migration automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Enonic Content Migration

Procedures

Step 1: Identify the Enonic XP project and operation scope

  1. Inspect the workspace for Enonic XP project markers: build.gradle with com.enonic.xp dependencies, src/main/resources/ directory structure, or gradle.properties with xpVersion.
  2. Execute node scripts/find-enonic-targets.mjs . to scan for Enonic XP project markers and existing content operation files when a Node runtime is available.
  3. If no Enonic XP project is detected, stop and explain that this skill targets Enonic XP content operations only.
  4. Determine the target XP version from gradle.properties or build.gradle to select the correct API surface.
  5. Classify the requested operation:
    • Bulk create: Importing content from external sources (JSON, CSV, APIs).
    • Bulk update: Modifying existing content matching query criteria.
    • Bulk delete: Removing content matching query criteria.
    • Migration: Moving or transforming content between paths, sites, or environments.
    • Query/Aggregation: Retrieving and analyzing content with NoQL and aggregations.
    • Long-running task: Any operation processing more than ~100 items that needs progress reporting.

Step 2: Select the API layer and context

  1. Read references/migration-reference.md for query DSL patterns, batch processing strategies, and branch handling rules.
  2. Choose lib-content when the operation works with CMS content and needs publish/unpublish, content-type validation, and the content domain abstraction.
  3. Choose lib-node when the operation needs low-level node manipulation, custom repositories, or bypasses content-type validation for raw data migration.
  4. Determine the required context:
    • Use lib-context to run operations in draft branch for modifications and master branch for reading published content.
    • Use lib-context with role:system.admin principal when the operation requires elevated permissions.
  5. If the operation processes more than ~100 items, wrap it in a task controller using lib-task. Read references/migration-reference.md section on task controllers for the pattern.

Step 3: Build the query

  1. Construct the NoQL query string or DSL expression to match the target content.
  2. For content-type filtering, use the contentTypes parameter on contentLib.query() or a type property comparison in node queries.
  3. For date-range queries, use instant() or dateTime() functions and the range() query function.
  4. For full-text search, use fulltext() with the appropriate field paths and operator (AND/OR).
  5. For path-scoped operations, use _path LIKE '/content/site-path/*' to match descendants. Note: the _path property in NoQL queries includes the internal /content/ prefix, but hit._path in results returns the content-domain path without it. Always prepend /content/ when building queries from result paths.
  6. Add filters for efficient post-query narrowing using exists, notExists, hasValue, or boolean combinations.
  7. Add aggregations when the operation needs grouped statistics (term counts, date histograms, numeric ranges, stats).
  8. Read references/examples.md for complete query and aggregation patterns.

Step 4: Implement batch processing

  1. Use paginated retrieval with start and count parameters to avoid loading all results into memory.
  2. Set count to a batch size between 50 and 200 depending on the complexity of per-item processing.
  3. Loop until result.hits.length === 0 or start >= result.total, incrementing start by the batch size each iteration.
  4. For contentLib.create() in bulk, set refresh: false to avoid per-item index refresh; call a manual refresh after the batch completes.
  5. For contentLib.modify(), use the editor callback pattern to safely transform each content item.
  6. For contentLib.publish(), batch keys into groups of 50–100 to avoid timeout on large publish sets.
  7. Track success and failure counts for reporting.
  8. Read assets/bulk-update.template.ts for the reusable batch update controller template. Note: templates use TypeScript/ESM syntax (import, const, arrow functions); adapt to CommonJS JavaScript (require(), var, function()) for XP runtime deployment as .js files.

Step 5: Handle branch operations and publishing

  1. Run content modifications in the draft branch context.
  2. After modifications complete, publish changed items to master using contentLib.publish(). On XP < 7.12, pass sourceBranch: 'draft' and targetBranch: 'master'. On XP 7.12+, these parameters are ignored (publish always goes draft→master).
  3. Set includeDependencies: false when publishing bulk-updated items to avoid unintended dependency publishing.
  4. For operations comparing draft and master state, use repo.diff() from lib-node with target: 'master' and includeChildren: true.

Step 6: Wrap long-running operations in a task controller

  1. Use taskLib.executeFunction() for inline task functions or taskLib.submitTask() for named task descriptors.
  2. Report progress using taskLib.progress({ info, current, total }) at regular intervals during batch processing.
  3. Read assets/task-migration.template.ts for the reusable task controller template with progress reporting.
  4. Check for existing running instances with taskLib.isRunning() before starting a duplicate operation.
  5. Use taskLib.sleep() for throttling between batches if the operation generates excessive load.
  6. For named tasks on XP 7.13+, the run function receives taskId as its second argument: exports.run = function(params, taskId) { ... }.

Step 7: Validate and report results

  1. After the operation completes, log a summary: items processed, items created/updated/deleted, items failed, total duration.
  2. For migration operations, verify target content exists by querying the destination path.
  3. For publish operations, verify published state by querying the master branch.
  4. If errors occurred, collect error details (content path, error message) into a structured report.

Error Handling

  • If scripts/find-enonic-targets.mjs finds no Enonic XP project, explain that the workspace does not contain an Enonic XP application.
  • If a content operation fails with contentAlreadyExists, check whether the target exists and decide whether to update or skip. Read references/troubleshooting.md for duplicate handling patterns.
  • If a query returns zero results, verify the query syntax, branch context, and property paths. NoQL string-format mismatches (e.g. missing instant() wrapper for date comparisons) are a common cause.
  • If a task fails or times out, check taskLib.get(taskId) for state and progress details. Read references/troubleshooting.md for timeout and permission issues.
  • If an AccessDeniedException occurs on publish or modify, ensure the context includes role:system.admin principals via lib-context.

FAQ

What does the enonic-content-migration skill do?

Generates Enonic XP scripts for bulk content operations — creating, updating, querying, migrating, and transforming content using lib-content and lib-node APIs. Covers the query DSL (NoQL), aggregations, batch processing, task controllers for long-running operations, and export/import workflows. Use when writing bulk content creation, update, or deletion scripts, querying with NoQL syntax, migrating content between environments, running long-running task operations, or working with aggregations and paginated retrieval. Do not use for Guillotine GraphQL frontend queries, content type schema definitions, single contentLib.get() calls, or non-Enonic data migration tools.

How do I install enonic-content-migration?

Run npx skills add https://github.com/webmaxru/enonic-agent-skills --skill enonic-content-migration in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/enonic-content-migration/ (personal) or .claude/skills/enonic-content-migration/ (project).

Which AI agents can use enonic-content-migration?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is enonic-content-migration safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains enonic-content-migration?

It is published by webmaxru in webmaxru/enonic-agent-skills. It has 143 recorded installs.

More from webmaxru/enonic-agent-skills

View all →

enonic-nextxp-integration

webmaxru/enonic-agent-skills

Open the skill to read its SKILL.md instructions.

AI & Agents462 installs

agent-skill-deploy

webmaxru/enonic-agent-skills

Deploys agent skill collections from any GitHub repository with a /skills folder to one or more distribution surfaces: GitHub releases, Claude Code marketplace, VS Code plugin marketplace, and Copilot CLI plugin marketplace. Handles pre-flight validation, conventional commit analysis, version bumping across surface configs, and surface-specific publishing with dry-run support. Use when releasing, publishing, or deploying a skills collection to any supported marketplace or creating a GitHub release for a skills repository. Don't use for deploying non-skill packages, npm modules, Docker images, or Azure resources.

DevOps & Cloud460 installs

enonic-content-type-generator

webmaxru/enonic-agent-skills

Generates Enonic XP content type XML schema definitions from natural-language descriptions. Covers structured content modeling including input types, form layout, option sets, item sets, mixins, x-data, and content-type inheritance. Use when creating, scaffolding, or generating Enonic XP content type definitions, adding fields or sets to existing content types, or querying Enonic XP input types and super-types. Do not use for non-Enonic content modeling, GraphQL queries, JavaScript/TypeScript controllers, or generic XML editing unrelated to Enonic schemas.

Frontend & Design460 installs

enonic-guillotine-query-builder

webmaxru/enonic-agent-skills

Open the skill to read its SKILL.md instructions.

AI & Agents457 installs

agent-package-manager

webmaxru/enonic-agent-skills

Installs, configures, audits, and operates Agent Package Manager (APM) in repositories. Use when initializing apm.yml, installing or updating packages, validating manifests, managing lockfiles, compiling agent context, browsing MCP servers, setting up runtimes, or packaging resolved context for CI and team distribution. Don't use for writing a single skill by hand, generic package managers like npm or pip, or non-APM agent configuration systems.

AI & Agents454 installs

github-agentic-workflows

webmaxru/enonic-agent-skills

Authors, reviews, installs, and debugs GitHub Agentic Workflows in repositories, including workflow markdown, frontmatter, gh aw compile and run flows, safe outputs, security guardrails, and operational patterns. Use when creating or maintaining GH-AW automation. Don't use for standard deterministic GitHub Actions YAML, generic CI pipelines, or non-GitHub automation systems.

AI & Agents453 installs

Popular code quality & workflow skills

View category →

grill-me

mattpocock/skills

A relentless interview to sharpen a plan or design.

Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.

handoff

mattpocock/skills

Compact the current conversation into a handoff document for another agent to pick up.

domain-modeling

mattpocock/skills

Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a GLOSSARY.md, or recording or editing an ADR.

codebase-design

mattpocock/skills

Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.

diagnosing-bugs

mattpocock/skills

Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.