handover-developer — Claude Code skill: what it does, how to install
Generates technical handover guides for AEM Edge Delivery Services codebases. Useful when onboarding engineers or documenting block architecture.
npx skills add adobe/skills --skill handover-developer -a claude-codeWhat handover-developer does
The skill checks for scripts/aem.js at the repository root. If that file is missing, execution stops immediately: the tool only operates on AEM Edge Delivery Services repositories and will fail on any other setup. To fetch site metadata, it prompts for the Config Service organization name and reads the IMS token from ~/.aem/ims-token.json.
Next, the skill inspects directories such as blocks/, scripts/, styles/, and templates/. It filters git history to ignore initial boilerplate and commits by aem-aemy[bot], documenting only what team members edited. After analyzing imports in scripts/scripts.js and exported methods in scripts/aem.js, it writes developer guides to project-guides/ and compiles a PDF.
What it helps with
- generate developer documentation for an AEM Edge Delivery Services repository
- filter out boilerplate and bot commits from project documentation
- map block implementations and custom logic in
scripts/scripts.js - export technical handover guides to PDF
Example prompts for the agent
- Create a developer handover guide for this AEM project
- Document our custom blocks and scripts architecture into project-guides
- Generate technical onboarding documentation for this repository
How to install handover-developer
1Skills CLI (Vercel)
npx skills add adobe/skills --skill handover-developer -a claude-code2Manually: put the files in place
~/.claude/skills/handover-developer/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/handover-developer/
1Skills CLI (Vercel)
npx skills add adobe/skills --skill handover-developer -a codex2Manually: put the files in place
.agents/skills/handover-developer/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add adobe/skills --skill handover-developer -a cursor2Manually: put the files in place
.cursor/skills/handover-developer/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install adobe/skills handover-developer2Manually: put the files in place
.github/skills/handover-developer/SKILL.md1Skills CLI (Vercel)
npx skills add adobe/skills --skill handover-developer -a gemini-cli2Platform CLI
gemini skills install https://github.com/adobe/skills --path plugins/aem/project-management/skills/handover-developerManually: put the files in place
.devin/skills/handover-developer/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add adobe/skills --skill handover-developer -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 handover-developer
How to install handover-developer in Claude Code?
Run npx skills add adobe/skills --skill handover-developer -a claude-code to add the skill to your Claude Code environment.
What does handover-developer do?
It inspects an AEM Edge Delivery Services codebase, separates custom code from boilerplate, and writes technical documentation to project-guides/ before producing a PDF.
What is required before running this skill?
Your project must contain scripts/aem.js at the root. You also need a valid IMS auth token in ~/.aem/ims-token.json and your Config Service organization name.
Source text
SKILL.md · Apache-2.0
---
name: handover-developer
description: Generate comprehensive technical documentation for developers taking over an AEM Edge Delivery Services project. Use when onboarding developers, creating technical handover documentation, or documenting a project's architecture — analyzes codebase structure, custom implementations, design tokens, and produces a complete developer guide.
license: Apache-2.0
allowed-tools: Read, Write, Edit, Bash, Skill, Glob, Grep
metadata:
version: "1.0.0"
---
# Project Handover - Development
Generate a complete technical guide for developers. Analyzes the codebase and produces actionable documentation that enables developers to understand, maintain, and extend the project.
---
## Step 0: Navigate to Project Root (CONDITIONAL)
Skip if `allGuides` is set in `.claude-plugin/project-config.json` (orchestrator already validated).
```bash
ALL_GUIDES=$(cat .claude-plugin/project-config.json 2>/dev/null | node -e "
const d = require('fs').readFileSync(0,'utf8');
try { console.log(JSON.parse(d).allGuides ? 'true' : ''); } catch(e) { console.log(''); }
")
if [ -z "$ALL_GUIDES" ]; then
cd "$(git rev-parse --show-toplevel)"
ls scripts/aem.js
fi
```
If `scripts/aem.js` does not exist, tell the user this skill requires an AEM Edge Delivery Services project and stop.
All subsequent steps operate from project root. Guides are created at `project-guides/`.
---
## Execution Checklist
```markdown
- [ ] Phase 0: Get org name and authenticate
- [ ] Phase 1: Gather project information
- [ ] Phase 2: Analyze project architecture
- [ ] Phase 3: Document design system
- [ ] Phase 4: Document blocks, models, and templates
- [ ] Phase 5: Generate PDF
```
---
## Phase 0: Get Organization Name and Authenticate
### 0.1 Check for Saved Organization
```bash
cat .claude-plugin/project-config.json 2>/dev/null | node -e "
const d = require('fs').readFileSync(0,'utf8');
try { const o = JSON.parse(d).org; if(o) console.log('org: ' + o); } catch(e) {}
"
```
### 0.2 Prompt for Organization Name (If Not Saved)
If no org name is found, ask the user:
> "What is your Config Service organization name? This is the `{org}` part of your Edge Delivery Services URLs (e.g., `https://main--site--{org}.aem.page`). The org name may differ from your GitHub organization."
Ask as a plain text question — not `AskUserQuestion` with options. Organization name is mandatory.
### 0.3 Save Organization Name
```bash
mkdir -p .claude-plugin
grep -qxF '.claude-plugin/' .gitignore 2>/dev/null || echo '.claude-plugin/' >> .gitignore
if [ -f .claude-plugin/project-config.json ]; then
cat .claude-plugin/project-config.json | sed 's/"org"[[:space:]]*:[[:space:]]*"[^"]*"/"org": "{ORG_NAME}"/' > /tmp/project-config.json && mv /tmp/project-config.json .claude-plugin/project-config.json
else
echo '{"org": "{ORG_NAME}"}' > .claude-plugin/project-config.json
fi
```
Replace `{ORG_NAME}` with the actual organization name.
### 0.4 Check Auth Token
```bash
AUTH_TOKEN=$(node -e "
const fs = require('fs');
try {
const t = JSON.parse(fs.readFileSync(process.env.HOME + '/.aem/ims-token.json', 'utf8'));
if (t.authToken && t.authTokenExpiry > Math.floor(Date.now()/1000) + 60) {
process.stdout.write(t.authToken);
}
} catch (e) {}
")
if [ -z "$AUTH_TOKEN" ]; then
echo "AUTH_REQUIRED"
fi
```
If `AUTH_REQUIRED`, invoke the auth skill:
```
Skill({ skill: "aem-project-management:auth" })
```
---
## Phase 1: Gather Project Information
### 1.1 Get Project URLs and Repository
```bash
git remote -v | head -1
git branch -a | head -10
```
Extract: repository owner, repo name, main branch name.
### 1.2 Check Configuration Method
```bash
ls helix-config.yaml 2>/dev/null && echo "Uses legacy helix-config" || echo "Uses Config Service (modern)"
```
### 1.3 Fetch Sites via Config Service API
The Config Service API is the only reliable source for site information. Do not use `fstab.yaml`, README, or git remote URLs.
```bash
ORG=$(cat .claude-plugin/project-config.json | node -e "
const d = require('fs').readFileSync(0,'utf8');
console.log(JSON.parse(d).org || '');
")
AUTH_TOKEN=$(node -e "
const fs = require('fs');
try {
const t = JSON.parse(fs.readFileSync(process.env.HOME + '/.aem/ims-token.json', 'utf8'));
process.stdout.write(t.authToken || '');
} catch (e) {}
")
curl -s -H "x-auth-token: ${AUTH_TOKEN}" -H "Accept: application/json" \
"https://admin.hlx.page/config/${ORG}/sites.json" > .claude-plugin/sites-config.json
node -e "
const d = require('fs').readFileSync('.claude-plugin/sites-config.json', 'utf8');
const j = JSON.parse(d);
if (!j.sites || !j.sites.length) {
console.error('No sites returned — verify org name and re-authenticate if needed');
process.exit(1);
}
console.log('Found ' + j.sites.length + ' site(s): ' + j.sites.map(s => s.name).join(', '));
"
```
If validation fails, verify the org name is correct, re-authenticate, and retry.
Fetch per-site config:
```bash
curl -s -H "x-auth-token: ${AUTH_TOKEN}" \
"https://admin.hlx.page/config/${ORG}/sites/{site-name}.json"
```
Extract: `code.owner`, `code.repo`, `content.source.url`, `content.source.type`.
Multiple sites = repoless setup. Single site = standard setup. Record this — it affects the `aem up` local dev instructions.
### 1.4 Check Node.js Requirements
```bash
cat .nvmrc 2>/dev/null || cat package.json | grep -A2 '"engines"'
```
---
## Phase 2: Analyze Project Architecture
Read site config:
```bash
cat .claude-plugin/sites-config.json
```
### 2.1 Map Project Structure
```bash
ls -la && ls -la blocks/ && ls -la scripts/ && ls -la styles/
ls -la templates/ 2>/dev/null || echo "No templates folder"
```
### 2.2 Identify Boilerplate vs Custom Files
Only document files that were actually customized.
```bash
git log --oneline --follow {file_path} | head -5
git log --format="%an - %s" --follow {file_path} | head -5
```
| Git History | Action |
|-------------|--------|
| Only "Initial commit" | Skip — boilerplate default, never worked on |
| Only `aem-aemy[bot]` commits | Skip — auto-generated |
| Multiple commits by team | Document — customized |
### 2.3 Analyze scripts/aem.js (Core Library)
```bash
grep -E "^export" scripts/aem.js
```
Document which functions the project imports from `aem.js` (e.g., `sampleRUM`, `loadHeader`, `loadFooter`, `decorateBlock`, `loadBlock`, `loadCSS`).
### 2.4 Analyze scripts/scripts.js
```bash
grep -E "^import|^export|^function|^async function|buildAutoBlocks|loadTemplate|getLanguage|getSiteRoot|decorateMain|loadEager|loadLazy|loadDelayed" scripts/scripts.js
```
Document:
| Pattern | What to Document |
|---------|-----------------|
| `import` statements | What it imports from `aem.js` and `utils.js` |
| `loadEager` / `loadLazy` | Any custom logic added to E-L-D phases |
| `buildAutoBlocks` | Auto-blocking logic |
| `loadTemplate` / template handling | Template system |
| `getLanguage` / language detection | Multi-language setup |
| `getSiteRoot` / site detection | Multi-site configuration |
| External script loading | Which phase — flag if in eager (performance risk) |
### 2.5 Analyze scripts/delayed.js
```bash
grep -E "^import|function|google|analytics|gtag|alloy|martech|OneTrust|launch|chatbot|widget" scripts/delayed.js
```
Document analytics integrations, marketing tools, performance monitoring. Confirm no render-critical code is in this file.
### 2.6 Check for Utility Functions
```bash
grep -E "^export|^function" scripts/utils.js 2>/dev/null || echo "No utils.js"
ls scripts/*.js
grep -rl "utils.js" blocks/ scripts/ 2>/dev/null
```
Document shared utility functions and which blocks/scripts import them.
### 2.7 Check for External Dependencies
```bash
grep -A 20 '"dependencies"' package.json 2>/dev/null | head -25
grep -r "cdn\|unpkg\|jsdelivr" scripts/ blocks/ --include="*.js" 2>/dev/null
```
---
## Phase 3: Document Design System
### 3.1 Extract CSS Custom Properties
```bash
grep -E "^\s*--" styles/styles.css
```
Organize into categories: Typography, Colors, Spacing, Layout.
### 3.2 Document Font Setup
```bash
grep -E "@font-face|font-family|font-weight|src:" styles/fonts.css 2>/dev/null
ls fonts/ 2>/dev/null
```
Document: font files and formats, family names, weights, fallback fonts.
### 3.3 Document Breakpoints
```bash
grep -E "@media.*min-width|@media.*max-width" styles/styles.css | sort -u
```
Standard breakpoints: Mobile < 600px, Tablet 600-899px, Desktop 900px+, Large 1200px+. Document any deviations.
### 3.4 Document Section Styles
```bash
grep -A 5 "\.section\." styles/styles.css
grep -A 5 "\.section\[" styles/styles.css
```
---
## Phase 4: Document Blocks, Models, and Templates
### Boilerplate Filtering
Run silently — do not show output to user.
- Include: Items with 2+ commits and at least one after "Initial commit"
- Exclude: Items with only "Initial commit" or only `aem-aemy[bot]` commits
### 4.1 Identify and Analyze Customized Blocks
```bash
head -30 blocks/{blockname}/{blockname}.js
grep -E "^\." blocks/{blockname}/{blockname}.css | head -30
grep -E "classList\.contains|classList\.add" blocks/{blockname}/{blockname}.js
```
Document for each customized block:
| Field | What to Record |
|-------|----------------|
| Name | Block folder name |
| Purpose | What it does |
| DOM Input | Expected HTML structure from CMS |
| DOM Output | Transformed structure after decoration |
| Variants | CSS classes that modify behavior |
| Dependencies | External libraries, other blocks, utils |
### 4.2 Document Universal Editor Models (If Customized)
Apply boilerplate filtering to `models/*.json`. Exclude standard boilerplate models (`_page.json`, `_section.json`, `_button.json`, `_image.json`, `_text.json`, `_title.json`) if unchanged. Skip section if all models are boilerplate.
### 4.3 Document Customized Templates
Apply boilerplate filtering to `templates/*/`. For each customized template, document purpose, how it's applied (`template: name` in metadata), and what it changes.
---
## Phase 5: Generate Developer Guide
### 5.1 Output File
Save to `project-guides/DEVELOPER-GUIDE.md` (run `mkdir -p project-guides` first).
Read `resources/developer-guide-template.md` for the full document structure. Fill in all sections using data gathered in Phases 1–4 — replace every `[placeholder]` with actual project values.
### 5.2 Convert to Professional PDF
Save the completed markdown to `project-guides/DEVELOPER-GUIDE.md` with YAML frontmatter (title, date using full date format e.g., "February 17, 2026"). Then immediately invoke PDF conversion:
```
Skill({ skill: "aem-project-management:whitepaper", args: "project-guides/DEVELOPER-GUIDE.md project-guides/DEVELOPER-GUIDE.pdf" })
```
The whitepaper skill auto-cleans source files. Final output: `project-guides/DEVELOPER-GUIDE.pdf`.
Inform the user: "Developer guide complete: project-guides/DEVELOPER-GUIDE.pdf"
---
## Success Criteria
| Category | Check |
|----------|-------|
| **Data Source** | Config Service API called (`https://admin.hlx.page/config/{ORG}/sites.json`) |
| **Data Source** | Site list from API response, not fstab.yaml or codebase analysis |
| **Data Source** | Repoless/standard determination from Config Service, not inferred from code |
| **Content** | Quick Reference with all project URLs |
| **Content** | Architecture overview accurate to project |
| **Content** | Design system fully documented (tokens, fonts, breakpoints) |
| **Content** | Project-specific blocks documented |
| **Content** | Custom scripts.js functions documented |
| **Content** | delayed.js integrations documented |
| **Content** | Templates documented (if applicable) |
| **Content** | Local development setup verified |
| **Content** | Common tasks have clear instructions |
| **Content** | Troubleshooting section covers common issues |
| **Output** | PDF generated at `project-guides/DEVELOPER-GUIDE.pdf` |
| **Output** | All source files cleaned up (only PDF remains) |
---
**Communication:** Never use "EDS" as an acronym — always write "Edge Delivery Services" or "AEM Edge Delivery Services" in all output and documentation.
© adobe · Apache-2.0 · adobe/skills