Claude
Skills
Sign in
Back

admin

Included with Lifetime
$97 forever

Generate comprehensive admin documentation for AEM Edge Delivery Services project handover. Creates admin guide covering Config Service setup, permissions, access control, Admin API operations, cache management, and code sync. Use for "admin guide", "admin documentation", "admin handover".

Backend & APIs

What this skill does


# Project Handover - Admin Guide

Generate comprehensive documentation for administrators taking over an AEM Edge Delivery Services project. Produces a complete admin guide with Config Service setup, permissions, Admin API operations, and troubleshooting.

## When to Use This Skill

- Project handover to client administrators
- Documenting admin procedures for a project
- Creating operations runbook
- "Generate admin guide"
- "Admin documentation"
- "Admin handover"

---

## Step 0: Navigate to Project Root and Verify Edge Delivery Services Project (CONDITIONAL)

**Skip this step if `allGuides` flag is set** (orchestrator already validated and navigated).

**CRITICAL: If NOT skipped, you MUST execute the `cd` command. Do NOT use absolute paths — actually change directory.**

```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
  # Navigate to git project root (works from any subdirectory)
  cd "$(git rev-parse --show-toplevel)"
  # Verify it's an Edge Delivery Services project
  ls scripts/aem.js
fi
```

**IMPORTANT:**
- You MUST run the `cd` command above using the Bash tool
- All subsequent steps operate from project root
- Do NOT use absolute paths to verify — actually navigate
- Guides will be created at `project-root/project-guides/`

**If NOT skipped AND `scripts/aem.js` does NOT exist**, respond:

> "This skill is designed for AEM Edge Delivery Services projects. The current directory does not appear to be an Edge Delivery Services project (`scripts/aem.js` not found).
>
> Please navigate to an Edge Delivery Services project and try again."

**STOP if check fails. Otherwise proceed — you are now at project root.**

---

## Execution Checklist

```markdown
- [ ] Phase 1: Gather Project Context
- [ ] Phase 2: Generate Admin Guide Content
- [ ] Phase 3: Customize for Project
- [ ] Phase 4: Generate Professional PDF
```

---

## Communication Guidelines

- **NEVER use "EDS"** as an acronym for Edge Delivery Services in any generated documentation or chat responses
- Always use the full name "Edge Delivery Services" or "AEM Edge Delivery Services"
- This applies to all output files (PDF, HTML, markdown) and all communication with the user

---

## ⚠️ CRITICAL PATH REQUIREMENT

**YOU MUST SAVE THE FILE TO THIS EXACT PATH:**

```
project-guides/ADMIN-GUIDE.md
```

**BEFORE WRITING ANY FILE:**
1. First, create the directory: `mkdir -p project-guides`
2. Then write to: `project-guides/ADMIN-GUIDE.md`

**WHY THIS MATTERS:** Files must be in `project-guides/` for proper organization and PDF conversion.

❌ **WRONG:** `ADMIN-GUIDE.md` (root)
❌ **WRONG:** `docs/ADMIN-GUIDE.md`
❌ **WRONG:** `/workspace/ADMIN-GUIDE.md`
✅ **CORRECT:** `project-guides/ADMIN-GUIDE.md`

---

## Output Format

**MANDATORY OUTPUT:** `project-guides/ADMIN-GUIDE.pdf`

**STRICTLY FORBIDDEN:**
- ❌ Do NOT read or analyze `fstab.yaml` — it does NOT exist in most projects and does NOT show all sites
- ❌ Do NOT create `.plain.html` files
- ❌ Do NOT use `convert_markdown_to_html` tool — this converts the FULL guide to HTML with raw frontmatter visible, which is NOT what we want
- ❌ Do NOT tell user to "convert markdown to PDF manually"
- ❌ Do NOT save markdown to root directory or any path other than `project-guides/`
- ❌ Do NOT say "PDF will be generated later" or "at session end" — generate it NOW

**The HTML output must be a SHORT summary page** (created with Write tool) containing:
- Title and brief description
- "What's Inside" bullet list
- PDF download link
NOT the full guide content converted to HTML.

**REQUIRED WORKFLOW:**
1. Run `mkdir -p project-guides` to ensure directory exists
2. Generate markdown content with YAML frontmatter (title, date)
3. Save to `project-guides/ADMIN-GUIDE.md` (EXACT PATH - no exceptions)
4. **IMMEDIATELY** invoke PDF conversion (see Phase 4.1)
5. Clean up all source files (only PDF remains)
6. Final output: `project-guides/ADMIN-GUIDE.pdf`

---

## Phase 0: Get Organization Name (Required First)

**Whenever this skill runs** — whether the user triggered it directly (e.g. "generate admin guide") or via the handover flow — you must have the Config Service organization name before doing anything else. Do not skip this phase.

### 0.1 Check for Saved Organization

```bash
# Check if org name is already saved
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 saved**, you MUST pause and ask the user directly:

> "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."

**IMPORTANT RULES:**
- **DO NOT use `AskUserQuestion` with predefined options** — ask as a plain text question
- **Organization name is MANDATORY** — do not offer a "skip" option
- **Wait for user to type the org name** before proceeding
- If user doesn't provide a valid org name, ask again

### 0.3 Save Organization Name

Once you have the org name (either from saved config or user input), save it for future use:

```bash
# Create config directory if needed
mkdir -p .claude-plugin
# Ensure .claude-plugin is in .gitignore (contains project config)
grep -qxF '.claude-plugin/' .gitignore 2>/dev/null || echo '.claude-plugin/' >> .gitignore

# Save org name to config file (create or update)
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 provided by the user.

---

## Phase 0.5: Authenticate with Adobe IMS

**After getting the organization name, authenticate to obtain an IMS token.**

### 0.5.1 Check for Existing Auth Token

```bash
IMS_TOKEN=$(node -e "
  const fs = require('fs');
  try {
    const t = JSON.parse(fs.readFileSync(process.env.HOME + '/.aem/ims-token.json', 'utf8'));
    if (t.imsToken && t.imsTokenExpiry > Math.floor(Date.now()/1000) + 60) {
      process.stdout.write(t.imsToken);
    }
  } catch (e) {}
")
IMS_EXPIRY=$(node -e "
  const fs = require('fs');
  try {
    const t = JSON.parse(fs.readFileSync(process.env.HOME + '/.aem/ims-token.json', 'utf8'));
    process.stdout.write(String(t.imsTokenExpiry || 0));
  } catch (e) { process.stdout.write('0'); }
")
NOW=$(date +%s)

if [ -n "$IMS_TOKEN" ] && [ "$IMS_EXPIRY" -gt "$((NOW + 60))" ]; then
  echo "Token valid (expires in $((IMS_EXPIRY - NOW)) seconds)"
else
  echo "Token missing or expired. Need to authenticate."
fi
```

### 0.5.2 Authenticate (If No Valid Token)

If no valid token exists, invoke the auth skill:

```
Skill({ skill: "project-management:auth" })
```

This will:
1. Open a browser for Adobe ID login
2. Capture the IMS OAuth token automatically
3. Save token to `~/.aem/ims-token.json` (user-level, shared across projects)
4. Auto-close the browser when complete

### 0.5.3 Verify Authentication

After auth skill completes, verify token works:

```bash
IMS_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.imsToken || '');
  } catch (e) {}
")
ORG=$(cat .claude-plugin/project-config.json | node -e "
  const d = require('fs').readFileSync(0,'utf8');
  console.log(JSON.parse(d).org || '');
")

# Test with authenticated endpoint
curl -s -w "%{http_code}" -o /dev/null -H "Authorization: B

Related in Backend & APIs