content-distribution — Claude Code skill for AEM publishing
Skill for AEM as a Cloud Service: publish content programmatically through the Replication API and watch distribution events.
npx skills add adobe/skills --skill content-distribution -a claude-codeWhat content-distribution does
The skill covers two jobs in AEM as a Cloud Service: publishing content from your own code and tracking how that content reaches the Publish or Preview tier. It is a parent skill and routes the task to one of two sub-skills — replication/SKILL.md for the Replication API and sling-distribution/SKILL.md for Sling Distribution events.
Publishing goes through com.day.cq.replication: Replicator, ReplicationOptions, ReplicationStatus, ReplicationActionType. Events come from org.apache.sling.distribution, with topics such as AGENT_PACKAGE_CREATED, AGENT_PACKAGE_QUEUED, AGENT_PACKAGE_DISTRIBUTED and IMPORTER_PACKAGE_IMPORTED. Ready-made patterns are included: publish and monitor, a preview-first flow that filters by agent id, and auto-publish on a resource change with failure handling.
The skill is marked beta and under active development, so review the output before it touches production. The source text is cut off, so the later steps and limits are not covered here.
What it helps with
- publish a page from a custom OSGi service instead of the UI
- wire publishing into a workflow process step
- run a bulk publish across a set of paths
- send content to Preview for approval, then to Publish
- catch the moment content actually goes live on the target tier
Example prompts for the agent
- Publish this page programmatically with the Replicator API
- Route the content to Preview first and to Publish after approval
- Register a handler for the event fired when the package is imported on the target tier
How to install content-distribution
1Skills CLI (Vercel)
npx skills add adobe/skills --skill content-distribution -a claude-code2Manually: put the files in place
~/.claude/skills/content-distribution/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/content-distribution/
1Skills CLI (Vercel)
npx skills add adobe/skills --skill content-distribution -a codex2Manually: put the files in place
.agents/skills/content-distribution/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add adobe/skills --skill content-distribution -a cursor2Manually: put the files in place
.cursor/skills/content-distribution/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install adobe/skills content-distribution2Manually: put the files in place
.github/skills/content-distribution/SKILL.md1Skills CLI (Vercel)
npx skills add adobe/skills --skill content-distribution -a gemini-cli2Platform CLI
gemini skills install https://github.com/adobe/skills --path plugins/aem/cloud-service/skills/content-distributionManually: put the files in place
.devin/skills/content-distribution/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add adobe/skills --skill content-distribution -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about content-distribution
How do I install content-distribution in Claude?
Run npx skills add adobe/skills --skill content-distribution -a claude-code. The skill lands in ~/.claude/skills/content-distribution/SKILL.md.
What does content-distribution do?
It gives the agent the official AEM as a Cloud Service APIs for publishing content and monitoring distribution events. Depending on the task it switches to the Replication API sub-skill or the Sling Distribution Events one.
Which APIs does it build on?
Two official ones: com.day.cq.replication for publishing and org.apache.sling.distribution for distribution events. Both are supported in AEM as a Cloud Service.
Source text
SKILL.md · Apache-2.0
---
name: content-distribution
license: Apache-2.0
description: |
AEM as a Cloud Service content distribution and replication. Covers programmatic publishing
using the Replication API and distribution event monitoring using Sling Distribution events.
---
# AEM Cloud Service Content Distribution
> **Beta Skill**: This skill is in beta and under active development.
> Results should be reviewed carefully before use in production.
> Report issues at https://github.com/adobe/skills/issues
Programmatic content publishing and distribution monitoring using official AEM Cloud Service APIs.
## When to Use This Skill
Use this skill collection for:
- **Programmatic publishing**: Publish content via `Replicator` API
- **Distribution monitoring**: Track distribution lifecycle events
- **Automated workflows**: Integration with workflow process steps
- **Event handling**: React to distribution events (failures, completions)
- **Custom publishing logic**: Bulk operations, Preview tier publishing
## Sub-Skills
This is a parent skill that routes to specialized sub-skills based on your task:
| Task | Sub-Skill | File |
|------|-----------|------|
| Programmatically publish/unpublish content | Replication API | [replication/SKILL.md](./replication/SKILL.md) |
| Monitor distribution events and lifecycle | Sling Distribution Events | [sling-distribution/SKILL.md](./sling-distribution/SKILL.md) |
## Quick Decision Guide
**Choose Replication API** when you need to:
- Publish content from custom OSGi services
- Integrate publishing into workflow steps
- Perform bulk publishing operations
- Publish to Preview tier for review
- Check replication status programmatically
**Choose Sling Distribution Events** when you need to:
- Monitor distribution lifecycle (created, queued, distributed, imported)
- React to distribution failures
- Trigger post-distribution actions (cache warming, notifications)
- Audit distribution operations
- Track distribution metrics
## Official APIs
Both skills use official, supported AEM Cloud Service APIs:
1. **Replication API**: `com.day.cq.replication`
- **Javadoc**: https://developer.adobe.com/experience-manager/reference-materials/cloud-service/javadoc/com/day/cq/replication/package-summary.html
- **Main Classes**: `Replicator`, `ReplicationOptions`, `ReplicationStatus`, `ReplicationActionType`
2. **Sling Distribution API**: `org.apache.sling.distribution`
- **Javadoc**: https://developer.adobe.com/experience-manager/reference-materials/cloud-service/javadoc/org/apache/sling/distribution/package-summary.html
- **Main Packages**: `org.apache.sling.distribution.event` (event topics and properties)
## Architecture Overview
```
┌──────────────────────────────────────────────────┐
│ Replication API (Your Code) │
│ com.day.cq.replication.Replicator │
│ │
│ replicator.replicate(session, ACTIVATE, path) │
└────────────────────┬─────────────────────────────┘
↓
┌──────────────────────────────────────────────────┐
│ Sling Distribution (Underlying Transport) │
│ org.apache.sling.distribution │
│ │
│ [AGENT_PACKAGE_CREATED] ← Distribution events │
│ ↓ fire at each stage │
│ [AGENT_PACKAGE_QUEUED] │
│ ↓ │
│ [AGENT_PACKAGE_DISTRIBUTED] │
│ ↓ │
│ Adobe Developer Pipeline Service │
│ ↓ │
│ [IMPORTER_PACKAGE_IMPORTED] │
└──────────────────────────────────────────────────┘
↓
Content live on Publish/Preview
```
### How It Works
1. **Your code** calls `Replicator.replicate()` to publish content
2. **Sling Distribution** packages content and fires `AGENT_PACKAGE_CREATED` event
3. Package is **queued** and `AGENT_PACKAGE_QUEUED` event fires
4. Package is **sent** to Adobe Developer pipeline and `AGENT_PACKAGE_DISTRIBUTED` event fires
5. Target tier **imports** content and `IMPORTER_PACKAGE_IMPORTED` event fires
6. Content is **live** on target tier (Publish or Preview)
## Common Patterns
### Pattern 1: Publish and Monitor
Publish content and track when it goes live:
```java
// Step 1: Publish using Replication API
@Reference
private Replicator replicator;
public void publishContent(Session session, String path) throws ReplicationException {
replicator.replicate(session, ReplicationActionType.ACTIVATE, path);
}
// Step 2: Monitor completion using Distribution Events
@Component(service = EventHandler.class, property = {
org.osgi.service.event.EventConstants.EVENT_TOPIC + "=" +
DistributionEventTopics.IMPORTER_PACKAGE_IMPORTED
})
public class PublishCompletionHandler implements EventHandler {
@Override
public void handleEvent(Event event) {
String[] paths = (String[]) event.getProperty(
DistributionEventProperties.DISTRIBUTION_PATHS
);
LOG.info("Content is now live: {}", String.join(",", paths));
// Trigger post-publish actions (cache warming, notifications, etc.)
}
}
```
### Pattern 2: Preview-First Workflow
Publish to Preview for approval, then to Publish:
```java
// Workflow Step 1: Publish to Preview
public void publishToPreview(Session session, String path) throws ReplicationException {
ReplicationOptions options = new ReplicationOptions();
options.setFilter(agent -> "preview".equals(agent.getId()));
replicator.replicate(session, ReplicationActionType.ACTIVATE, path, options);
}
// Workflow Step 2: After approval, publish to Publish tier
public void publishToProduction(Session session, String path) throws ReplicationException {
ReplicationOptions options = new ReplicationOptions();
options.setFilter(agent -> "publish".equals(agent.getId()));
replicator.replicate(session, ReplicationActionType.ACTIVATE, path, options);
}
```
### Pattern 3: Auto-Publish with Failure Handling
Auto-publish content and alert on failures:
```java
// Publish handler
@Component(service = EventHandler.class, property = {
org.osgi.service.event.EventConstants.EVENT_TOPIC + "=" +
SlingConstants.TOPIC_RESOURCE_CHANGED
})
public class AutoPublishHandler implements EventHandler {
@Reference
private Replicator replicator;
@Override
public void handleEvent(Event event) {
String path = (String) event.getProperty(SlingConstants.PROPERTY_PATH);
if (shouldAutoPublish(path)) {
try (ResourceResolver resolver = getServiceResolver()) {
Session session = resolver.adaptTo(Session.class);
replicator.replicate(session, ReplicationActionType.ACTIVATE, path);
} catch (Exception e) {
LOG.error("Auto-publish failed", e);
}
}
}
}
// Failure monitoring
@Component(service = EventHandler.class, property = {
org.osgi.service.event.EventConstants.EVENT_TOPIC + "=" +
DistributionEventTopics.AGENT_PACKAGE_DROPPED
})
public class FailureAlertHandler implements EventHandler {
@Reference
private AlertService alertService;
@Override
public void handleEvent(Event event) {
String packageId = (String) event.getProperty(
DistributionEventProperties.DISTRIBUTION_PACKAGE_ID
);
alertService.sendAlert("Distribution failed", packageId);
}
}
```
## Rate Limits and Constraints
| Constraint | Limit | Impact |
|-----------|-------|--------|
| Paths per API call (recommended) | 100 | Transactional guarantee; system auto-splits above this |
| Payload size | 10 MB | Excluding binaries |
> **Note**: `ReplicationOptions.setUseAtomicCalls()` is `@Deprecated` / "no longer required" per the Cloud Service Javadoc — the system handles auto-bucketing automatically for >100 paths.
**Best Practice**: For large hierarchical content trees, use the Tree Activation workflow step instead of custom code.
## Key Differences from AEM 6.x
| Feature | AEM 6.x | AEM Cloud Service |
|---------|---------|-------------------|
| Replication API | `com.day.cq.replication.Replicator` | ✅ Same API |
| Replication agents | Manual configuration | ✅ Automatic (managed by Adobe) |
| Transport mechanism | Direct JCR replication | ✅ Sling Distribution via Adobe pipeline |
| Preview tier | Not available | ✅ Available (requires agent filtering) |
| Distribution events | Limited | ✅ Full lifecycle via `org.apache.sling.distribution.event` |
| Agent configuration | Manual OSGi config | ❌ Not exposed (managed by Adobe) |
## When NOT to Use These Skills
**Use UI workflows instead** when:
- Publishing small amounts of content manually
- One-off publishing operations
- Content authors can use Quick Publish or Manage Publication
**Use Tree Activation workflow** when:
- Publishing large hierarchical content trees
- Bulk operations across hundreds of paths and no custom logic is needed
## Quick Reference
### Replication API Basics
```java
// Inject service
@Reference
private Replicator replicator;
// Publish single page
replicator.replicate(session, ReplicationActionType.ACTIVATE, "/content/mysite/page");
// Unpublish
replicator.replicate(session, ReplicationActionType.DEACTIVATE, "/content/mysite/page");
// Bulk publish (≤100 for transactional guarantee)
replicator.replicate(session, ReplicationActionType.ACTIVATE,
new String[]{"/content/page1", "/content/page2"}, null);
// Publish to Preview
ReplicationOptions options = new ReplicationOptions();
options.setFilter(agent -> "preview".equals(agent.getId()));
replicator.replicate(session, ReplicationActionType.ACTIVATE, "/content/page", options);
// Check status
ReplicationStatus status = replicator.getReplicationStatus(session, "/content/page");
boolean isPublished = status != null && status.isActivated();
```
### Distribution Event Handling Basics
```java
// Listen for distribution events
@Component(service = EventHandler.class, property = {
org.osgi.service.event.EventConstants.EVENT_TOPIC + "=" +
DistributionEventTopics.AGENT_PACKAGE_CREATED,
org.osgi.service.event.EventConstants.EVENT_TOPIC + "=" +
DistributionEventTopics.AGENT_PACKAGE_DISTRIBUTED,
org.osgi.service.event.EventConstants.EVENT_TOPIC + "=" +
DistributionEventTopics.AGENT_PACKAGE_DROPPED,
org.osgi.service.event.EventConstants.EVENT_TOPIC + "=" +
DistributionEventTopics.IMPORTER_PACKAGE_IMPORTED
})
public class DistributionMonitor implements EventHandler {
@Override
public void handleEvent(Event event) {
String topic = event.getTopic();
String packageId = (String) event.getProperty(
DistributionEventProperties.DISTRIBUTION_PACKAGE_ID
);
String[] paths = (String[]) event.getProperty(
DistributionEventProperties.DISTRIBUTION_PATHS
);
// Handle event based on topic
if (DistributionEventTopics.AGENT_PACKAGE_DROPPED.equals(topic)) {
LOG.error("Distribution failed: {}", packageId);
} else if (DistributionEventTopics.IMPORTER_PACKAGE_IMPORTED.equals(topic)) {
LOG.info("Content is live: {}", String.join(",", paths));
}
}
}
```
## Best Practices
1. **Use the right API**: Replication API for publishing, Distribution events for monitoring
2. **Respect rate limits**: ≤100 paths for transactional guarantee
3. **Handle failures**: Always catch `ReplicationException`, monitor `AGENT_PACKAGE_DROPPED` events
4. **Use service users**: Never use admin credentials
5. **Filter events appropriately**: Only listen to events you need
6. **Validate permissions**: Call `replicator.checkPermission()` before replication
7. **Publish only what's needed**: Avoid unnecessary bulk operations
## Troubleshooting
### Replication Issues
| Issue | Solution |
|-------|----------|
| `ReplicationException` | Check service user has `crx:replicate` permission |
| Content not on target tier | Verify agent filter, check replication status |
| "Too many paths" error | Use ≤100 paths for transactional guarantee, or pass all paths — system auto-splits |
### Event Handling Issues
| Issue | Solution |
|-------|----------|
| Event handler not firing | Verify event topic constant matches exactly |
| Missing event properties | Always null-check event properties |
| Handler slowing distribution | Use async job processing, don't block |
## Detailed Documentation
For detailed examples, code samples, and advanced usage:
- **Replication API**: See [replication/SKILL.md](./replication/SKILL.md)
- **Sling Distribution Events**: See [sling-distribution/SKILL.md](./sling-distribution/SKILL.md)
## References
- **Replication Javadoc**: https://developer.adobe.com/experience-manager/reference-materials/cloud-service/javadoc/com/day/cq/replication/package-summary.html
- **Sling Distribution Javadoc**: https://developer.adobe.com/experience-manager/reference-materials/cloud-service/javadoc/org/apache/sling/distribution/package-summary.html
- **Adobe Documentation**: https://experienceleague.adobe.com/docs/experience-manager-cloud-service/content/operations/replication.html
- **Sling Distribution**: https://sling.apache.org/documentation/bundles/content-distribution.html
- **Service Users / Repo Init**: https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/developing/aem-project-content-package-structure#repo-init
© adobe · Apache-2.0 · adobe/skills