Skip to content

Commit b8cc345

Browse files
kptdobeclaude
andauthored
feat(create-site): add create-site onboarding skill for AEM EDS (#68)
* feat(create-site): add create-site onboarding skill for AEM EDS Adds a new skill that automates the full zero-to-site onboarding flow: GitHub repo creation from boilerplate, aem-code-sync installation, DA content creation (nav/footer/index), and preview triggering. Includes learnings from a real end-to-end run: - da-auth-helper is installed from GitHub, not npm - DA-sourced content requires Bearer auth on preview requests - curl inline multiline content fails; temp files + @ syntax required - /usr/bin/curl needed explicitly to avoid PATH issues in subshells Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(create-site): address PR review feedback and add eval - Rewrite description to be utilitarian (remove 'zero-knowledge') - Remove Node.js version pin (18+ is archaic, loosen to just Node.js) - Generalise TodoWrite reference to agent-agnostic language - Add create-site-onboarding eval covering the non-obvious DA-specific behaviours: cache-first token auth, preview Bearer requirement, curl temp-file pattern, and aem-code-sync verification Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b68b08c commit b8cc345

File tree

6 files changed

+379
-1
lines changed

6 files changed

+379
-1
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"context": "Tests whether the agent correctly executes the full AEM EDS site creation flow: collecting inputs, creating the GitHub repo from the boilerplate template, handling the aem-code-sync human handoff with verification, authenticating with DA using a cache-first approach, creating nav/footer/index content via DA API, and triggering preview with the required Bearer auth. Covers the non-obvious DA-specific behaviours that trip up agents without this skill.",
3+
"type": "weighted_checklist",
4+
"checklist": [
5+
{
6+
"name": "Inputs collected before any API call",
7+
"max_score": 5,
8+
"description": "Agent collects GitHub org, repo name, and site name from the user before attempting any automated step"
9+
},
10+
{
11+
"name": "GitHub repo created from aem-boilerplate template",
12+
"max_score": 12,
13+
"description": "Agent uses gh CLI or GitHub API to create the repo specifically from the adobe/aem-boilerplate template, not a blank repo"
14+
},
15+
{
16+
"name": "aem-code-sync handoff correctly signalled",
17+
"max_score": 12,
18+
"description": "Agent provides the GitHub App installation URL, instructs the user to select only the new repo, and explicitly waits for user confirmation before continuing"
19+
},
20+
{
21+
"name": "aem-code-sync installation verified programmatically",
22+
"max_score": 8,
23+
"description": "After user confirmation, agent checks admin.hlx.page/status/{org}/{repo}/main/ returns a valid JSON response before proceeding to DA steps"
24+
},
25+
{
26+
"name": "DA auth uses cache-first approach",
27+
"max_score": 10,
28+
"description": "Agent checks ~/.aem/da-token.json for a valid cached token and its expiry before attempting a new OAuth flow or asking the user for a token"
29+
},
30+
{
31+
"name": "All three mandatory pages created in DA",
32+
"max_score": 15,
33+
"description": "Agent creates nav.html, footer.html, and index.html in DA (admin.da.live/source/{org}/{repo}/) with structurally correct HTML and the site name substituted"
34+
},
35+
{
36+
"name": "DA API calls use temp files, not inline multiline content",
37+
"max_score": 8,
38+
"description": "Agent writes HTML to temp files and uses the @ syntax for the curl -F flag rather than passing multiline content inline (inline multiline causes curl exit 26)"
39+
},
40+
{
41+
"name": "Preview requests include Bearer auth",
42+
"max_score": 15,
43+
"description": "Agent sends POST requests to admin.hlx.page/preview for nav, footer, and index — all with an Authorization: Bearer header. DA-sourced content returns 401 without it even on public repos."
44+
},
45+
{
46+
"name": "Complete hand-off delivered",
47+
"max_score": 10,
48+
"description": "Agent provides the preview URL (https://main--{repo}--{org}.aem.page/), DA content browser link, individual page edit links, and GitHub repo URL"
49+
},
50+
{
51+
"name": "Human handoff points clearly distinguished from automated steps",
52+
"max_score": 5,
53+
"description": "Agent clearly labels which steps require human action versus which it executes automatically, and does not proceed past handoff points without confirmation"
54+
}
55+
]
56+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Create a New AEM Edge Delivery Site
2+
3+
## Problem/Feature Description
4+
5+
A developer wants to create a brand-new AEM Edge Delivery Services site. They have a GitHub account under the organization `acme-org` and want the repository to be named `acme-site`, with a site display name of "Acme Site". They have an Adobe IMS account with access to DA (da.live).
6+
7+
## Output Specification
8+
9+
Walk through the complete site creation flow using the create-site skill. Execute each automated step directly — do not stop to explain what you would do. Clearly signal the two steps that require human action (aem-code-sync installation and DA authentication if no cached token is available), and wait for confirmation before continuing past each. Deliver a live preview URL and DA editing links at the end.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"extends": "../../../../../release.config.cjs"}
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
---
2+
name: create-site
3+
description: Creates a new AEM Edge Delivery site from scratch — GitHub repo from the boilerplate, aem-code-sync installation, initial DA content (nav, footer, homepage), and a live preview URL. Use this skill whenever a user wants to create a new AEM Edge Delivery site and no repository or DA content exists yet.
4+
license: Apache-2.0
5+
metadata:
6+
version: "1.0.0"
7+
---
8+
9+
# Create a New AEM Edge Delivery Site
10+
11+
This skill walks through the full onboarding flow for a new AEM Edge Delivery site. It handles everything that can be automated and clearly signals the steps that require human action.
12+
13+
## When to Use This Skill
14+
15+
Use this skill when:
16+
- A user wants to create a brand-new AEM Edge Delivery site from scratch
17+
- A user asks to "set up a new site", "create a new EDS project", or "onboard a new site"
18+
- No GitHub repository or DA content exists yet for the project
19+
20+
**Do NOT use this skill for:**
21+
- Importing or migrating existing pages (use **page-import** skill)
22+
- Building or modifying blocks on an existing site (use **content-driven-development** skill)
23+
24+
## Prerequisites
25+
26+
- A GitHub account with permission to create repositories in the target org
27+
- An Adobe IMS account with access to DA (da.live)
28+
- `gh` CLI authenticated (`gh auth status`) or a GitHub personal access token with `repo` scope
29+
- Node.js (for DA token management via da-auth-helper)
30+
31+
## Related Skills
32+
33+
- **page-import** — Import existing pages into the newly created site
34+
- **content-driven-development** — Build and modify blocks once the site exists
35+
- **building-blocks** — Implement new block code
36+
37+
---
38+
39+
## Step 0: Create TodoList
40+
41+
Create a checklist to track progress (use your agent's task-tracking tool if available):
42+
43+
1. **Gather inputs** — org, repo name, site name collected
44+
2. **Create GitHub repository** — repo created from boilerplate template
45+
3. **Install aem-code-sync** *(human action)* — GitHub App installed on repo
46+
4. **Authenticate with DA** — valid IMS token obtained
47+
5. **Create initial content in DA** — nav, footer, index created
48+
6. **Trigger preview** — all three paths return 200/201
49+
7. **Hand off** — preview URL and DA links delivered to user
50+
51+
---
52+
53+
## Step 1: Gather Inputs
54+
55+
Ask the user for the following. Do not proceed until all required inputs are provided.
56+
57+
1. **GitHub org** — the GitHub organization or username where the repo will be created (e.g. `my-org`)
58+
2. **Project name** — the repository name, lowercase, hyphens only (e.g. `my-site`)
59+
3. **Site name** — the human-readable name used in content (e.g. `My Site`). If not provided, derive it from the project name.
60+
61+
Store as: `{{ORG}}`, `{{REPO}}`, `{{SITE_NAME}}`
62+
63+
---
64+
65+
## Step 2: Create GitHub Repository
66+
67+
Create a new repository using the `adobe/aem-boilerplate` template.
68+
69+
**Option A — GitHub CLI (preferred, handles auth automatically):**
70+
```bash
71+
gh repo create {{ORG}}/{{REPO}} \
72+
--template adobe/aem-boilerplate \
73+
--description "{{SITE_NAME}} — AEM Edge Delivery site" \
74+
--public
75+
```
76+
77+
Check if `gh` is available with `gh auth status`. If not authenticated, run `gh auth login` first.
78+
79+
**Option B — GitHub API (if `gh` CLI is not available):**
80+
```
81+
POST https://api.github.com/repos/adobe/aem-boilerplate/generate
82+
Authorization: Bearer {{GITHUB_TOKEN}}
83+
Content-Type: application/json
84+
85+
{
86+
"owner": "{{ORG}}",
87+
"name": "{{REPO}}",
88+
"description": "{{SITE_NAME}} — AEM Edge Delivery site",
89+
"private": false,
90+
"include_all_branches": false
91+
}
92+
```
93+
94+
To obtain a token: https://github.com/settings/tokens/new — scope: `repo`.
95+
96+
**Success:** HTTP 201 (API) or exit code 0 (CLI). The repo is now live at `https://github.com/{{ORG}}/{{REPO}}`.
97+
98+
---
99+
100+
## Step 3: Install aem-code-sync *(human action required)*
101+
102+
The aem-code-sync GitHub App connects the repository to AEM's content delivery pipeline. This step cannot be automated — the user must complete it in the browser.
103+
104+
Tell the user:
105+
106+
> **Action required:** Install the AEM Code Sync app on your new repository.
107+
>
108+
> 1. Open this URL: https://github.com/apps/aem-code-sync/installations/new
109+
> 2. Under "Repository access", select **Only select repositories**
110+
> 3. Choose **{{ORG}}/{{REPO}}** from the list
111+
> 4. Click **Save**
112+
>
113+
> Reply "done" when complete.
114+
115+
Wait for confirmation before proceeding.
116+
117+
**Verify:** After confirmation, check that `https://admin.hlx.page/status/{{ORG}}/{{REPO}}/main/` returns a valid JSON response (not 404). If it does, the app is correctly installed.
118+
119+
---
120+
121+
## Step 4: Authenticate with DA
122+
123+
DA requires Adobe IMS authentication. Choose the appropriate path:
124+
125+
**Option A — da-auth-helper (preferred)**
126+
127+
`da-auth-helper` (https://github.com/adobe-rnd/da-auth-helper) caches IMS tokens at `~/.aem/da-token.json`. Always check the cache first before triggering a new OAuth flow.
128+
129+
1. Check for a valid cached token:
130+
```bash
131+
node -e "
132+
const fs = require('fs');
133+
const p = process.env.HOME + '/.aem/da-token.json';
134+
if (!fs.existsSync(p)) { console.log('No cache'); process.exit(1); }
135+
const t = JSON.parse(fs.readFileSync(p));
136+
console.log('Valid:', t.expires_at > Date.now());
137+
console.log('Expires:', new Date(t.expires_at).toISOString());
138+
"
139+
```
140+
141+
2. If valid, capture the token and skip to Step 5:
142+
```bash
143+
DA_TOKEN=$(node -e "const t = require(process.env.HOME + '/.aem/da-token.json'); process.stdout.write(t.access_token);")
144+
```
145+
146+
3. If missing or expired, install da-auth-helper from GitHub (it is not published to npm) and refresh:
147+
```bash
148+
npm install -g github:adobe-rnd/da-auth-helper
149+
da-auth-helper token
150+
```
151+
This opens a browser for Adobe IMS login and writes the new token to `~/.aem/da-token.json`. Then capture it as in step 2.
152+
153+
**Option B — DA MCP is configured**
154+
155+
If the DA MCP server is available, trigger the authentication tool to start the OAuth flow and share the authorization URL with the user.
156+
157+
**Option C — Manual token**
158+
159+
Ask the user to obtain an IMS token from their browser (e.g. from the DA network tab or an existing session) and paste it. Store as `{{DA_TOKEN}}`.
160+
161+
---
162+
163+
## Step 5: Create Initial Content in DA
164+
165+
Create the three mandatory pages every EDS site requires. Use the templates below exactly — they are pre-validated for EDS compliance.
166+
167+
**Option A — DA MCP:**
168+
Call the DA create source tool three times with the content below.
169+
170+
**Option B — DA API:**
171+
172+
Write each file to a temp file first, then POST using `@` syntax. Inline multiline content with `-F 'data=...'` causes curl to fail (exit 26). Use `/usr/bin/curl` explicitly to avoid PATH resolution issues in subshells.
173+
174+
```bash
175+
cat > /tmp/nav.html << 'EOF'
176+
<nav content>
177+
EOF
178+
/usr/bin/curl -s -o /dev/null -w "%{http_code}" -X POST "https://admin.da.live/source/{{ORG}}/{{REPO}}/nav.html" \
179+
-H "Authorization: Bearer {{DA_TOKEN}}" \
180+
-F "data=@/tmp/nav.html;type=text/html"
181+
```
182+
183+
Repeat for `footer.html` and `index.html`.
184+
185+
**Verify:** After each POST, expect HTTP 201. If you get 401, the token has expired — return to Step 4.
186+
187+
---
188+
189+
### nav.html
190+
191+
```html
192+
<main>
193+
<div>
194+
<p><a href="/">{{SITE_NAME}}</a></p>
195+
</div>
196+
<div>
197+
<ul>
198+
<li><a href="/">Home</a></li>
199+
</ul>
200+
</div>
201+
<div></div>
202+
</main>
203+
```
204+
205+
### footer.html
206+
207+
```html
208+
<main>
209+
<div>
210+
<p>© 2024 {{SITE_NAME}}. All rights reserved.</p>
211+
</div>
212+
</main>
213+
```
214+
215+
### index.html
216+
217+
```html
218+
<main>
219+
<div>
220+
<h1>Welcome to {{SITE_NAME}}</h1>
221+
<p>Your new site is ready. Start editing this page in DA.</p>
222+
</div>
223+
</main>
224+
```
225+
226+
---
227+
228+
## Step 6: Trigger Preview
229+
230+
Preview pulls the DA content into the AEM delivery pipeline and makes it accessible on the `.aem.page` domain.
231+
232+
DA-sourced content requires the Bearer token on preview requests — even for public repos. Use `/usr/bin/curl` explicitly.
233+
234+
```bash
235+
/usr/bin/curl -s -o /dev/null -w "%{http_code}" -X POST "https://admin.hlx.page/preview/{{ORG}}/{{REPO}}/main/nav" \
236+
-H "Authorization: Bearer {{DA_TOKEN}}"
237+
/usr/bin/curl -s -o /dev/null -w "%{http_code}" -X POST "https://admin.hlx.page/preview/{{ORG}}/{{REPO}}/main/footer" \
238+
-H "Authorization: Bearer {{DA_TOKEN}}"
239+
/usr/bin/curl -s -o /dev/null -w "%{http_code}" -X POST "https://admin.hlx.page/preview/{{ORG}}/{{REPO}}/main/" \
240+
-H "Authorization: Bearer {{DA_TOKEN}}"
241+
```
242+
243+
**Success:** HTTP 200 or 201 for each. The homepage is now live at:
244+
```
245+
https://main--{{REPO}}--{{ORG}}.aem.page/
246+
```
247+
248+
---
249+
250+
## Step 7: Confirm and Hand Off
251+
252+
Tell the user:
253+
254+
> **Your site is ready!**
255+
>
256+
> - **Preview:** `https://main--{{REPO}}--{{ORG}}.aem.page/`
257+
> - **Browse content in DA:** `https://da.live/#/{{ORG}}/{{REPO}}/`
258+
> - **Edit homepage:** `https://da.live/edit#/{{ORG}}/{{REPO}}/index`
259+
> - **Edit nav:** `https://da.live/edit#/{{ORG}}/{{REPO}}/nav`
260+
> - **Edit footer:** `https://da.live/edit#/{{ORG}}/{{REPO}}/footer`
261+
> - **GitHub repo:** `https://github.com/{{ORG}}/{{REPO}}`
262+
>
263+
> To start developing locally:
264+
> ```bash
265+
> git clone https://github.com/{{ORG}}/{{REPO}}.git
266+
> cd {{REPO}}
267+
> npm install
268+
> aem up
269+
> ```
270+
>
271+
> What would you like to do next — add more pages, customize a block, or set up a custom domain?
272+
273+
---
274+
275+
## Troubleshooting
276+
277+
| Symptom | Likely cause | Fix |
278+
|---|---|---|
279+
| Step 2 returns 422 | Repo name already exists | Ask user for a different name |
280+
| Step 3 verify returns 404 | aem-code-sync not installed | Re-send the installation URL |
281+
| Step 4 cached token missing/expired | No prior DA session on this machine | Install da-auth-helper from GitHub (`npm install -g github:adobe-rnd/da-auth-helper`) and run `da-auth-helper token` |
282+
| Step 5 curl exits with code 26 | Inline multiline content in `-F` flag | Write content to a temp file and use `@/tmp/file.html` syntax |
283+
| Step 5 returns 401 | Expired or missing IMS token | Re-check `~/.aem/da-token.json` expiry; ask user for a fresh token |
284+
| Step 5 returns 403 | Token lacks permission for this org/repo | Confirm the user has write access to `{{ORG}}/{{REPO}}` in DA |
285+
| Step 6 returns 401 | DA-sourced content requires auth on preview | Add `-H "Authorization: Bearer {{DA_TOKEN}}"` to preview requests |
286+
| Step 6 returns 404 | aem-code-sync not installed correctly | Verify Step 3, then retry |
287+
| `curl: command not found` in scripts | PATH not resolved in subshell | Use `/usr/bin/curl` explicitly |
288+
| Preview URL shows blank page | nav or index not previewed | Re-run Step 6 for the failing path |
289+
290+
---
291+
292+
## Reference
293+
294+
- Boilerplate: https://github.com/adobe/aem-boilerplate
295+
- aem-code-sync app: https://github.com/apps/aem-code-sync
296+
- DA docs: https://da.live/docs
297+
- DA Admin API: https://opensource.adobe.com/da-admin/
298+
- DA Auth (IMS token helper): https://github.com/adobe-rnd/da-auth-helper
299+
- AEM Admin API: https://www.aem.live/docs/admin.html
300+
- Full onboarding guide: https://www.aem.live/developer/create-site.md
301+
302+
### DA URL patterns
303+
304+
- Browse folder: `https://da.live/#/{{org}}/{{repo}}{{folder-path}}`
305+
- Edit HTML document: `https://da.live/edit#/{{org}}/{{repo}}{{path-without-extension}}`
306+
- Edit JSON/sheet: `https://da.live/sheet#/{{org}}/{{repo}}{{path-without-extension}}`
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "create-site",
3+
"version": "0.0.0-semantically-released",
4+
"private": true
5+
}

skills/aem/edge-delivery-services/tile.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"name": "adobe/aem-edge-delivery-services",
33
"version": "0.1.0",
4-
"summary": "Skills for building AEM Edge Delivery Services sites — block development, content modeling, code review, testing, and page import.",
4+
"summary": "Skills for building AEM Edge Delivery Services sites — site creation, block development, content modeling, code review, testing, and page import.",
55
"private": false,
66
"skills": {
77
"analyze-and-plan": { "path": "skills/analyze-and-plan/SKILL.md" },
8+
"create-site": { "path": "skills/create-site/SKILL.md" },
89
"authoring-analysis": { "path": "skills/authoring-analysis/SKILL.md" },
910
"block-collection-and-party": { "path": "skills/block-collection-and-party/SKILL.md" },
1011
"block-inventory": { "path": "skills/block-inventory/SKILL.md" },

0 commit comments

Comments
 (0)