aem-eds-kit 0.4.48 → 0.4.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +134 -58
- package/README.md +166 -42
- package/dist/bin/eds.js +166 -122
- package/package.json +1 -1
- package/samples/hero.svg +46 -29
package/README.md
CHANGED
|
@@ -12,13 +12,23 @@
|
|
|
12
12
|
|
|
13
13
|
**Turn a design into an EDS block** - JS, CSS and a Universal Editor model - without leaving your terminal.
|
|
14
14
|
|
|
15
|
-
`aem-eds-kit` gives you the `eds` command. Paste a design link
|
|
15
|
+
`aem-eds-kit` gives you the `eds` command. Paste a design link (a Figma frame, a Framer or Google Stitch page, or any web page) and it hands the design to the AI agent you already use: Claude Code, Cursor or Codex, or a local model through Ollama / oMLX. The agent writes the block straight into your repo. Figma is read through its REST API or MCP; web pages are **scraped with headless Chromium**, no token needed.
|
|
16
16
|
|
|
17
|
-
It lives next to `@adobe/aem-cli` (your
|
|
17
|
+
It lives next to `@adobe/aem-cli` (your `aem up` dev server) and handles everything around it: new projects, blocks, migration from AEM, previews, checks and publishing.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g aem-eds-kit
|
|
21
|
+
eds new my-site && cd my-site # the latest Adobe boilerplate
|
|
22
|
+
eds block from-design "<design link>" --name hero # design → blocks/hero/
|
|
23
|
+
eds block preview hero # see it in the browser
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Contents:** [What it does](#what-it-does) · [Install](#install) · [Try it](#try-it-in-30-seconds-no-figma-account-no-token) · [Interactive mode](#interactive-mode) · [Commands](#commands) · [Figma](#how-figma-integration-works) · [Local models](#local-models-ollama-omlx) · [Configuration](#configuration) · [Roadmap](#roadmap)
|
|
18
27
|
|
|
19
28
|
## What it does
|
|
20
29
|
|
|
21
|
-
- **
|
|
30
|
+
- **A new project in one command.** `eds new` clones Adobe's latest boilerplate (Document Authoring, Universal Editor or Commerce) without a GitHub login, and `eds init` sets it up for your authoring model.
|
|
31
|
+
- **Blocks from a design.** A Figma frame (REST or MCP), a Framer / Google Stitch page or any other web page (scraped with headless Chromium), or a local PNG / SVG export becomes `blocks/<name>/`: JS, CSS, a Universal Editor model and a preview mock. Works with Claude Code, Cursor and Codex, or a [local model](#local-models-ollama-omlx) through Ollama or oMLX. Content Fragment blocks (`--source cf` / `mixed`) get an async, fetching `decorate()`.
|
|
22
32
|
- **Migration from AEM.** `eds migrate component` turns a classic component's dialog into a block and a UE model, with no agent involved. It handles AEM as a Cloud Service proxy components (via `sling:resourceSuperType`, e.g. onto Core Components) and AEM 6.5 Classic UI `dialog.xml` files.
|
|
23
33
|
- **Within Figma's limits.** One REST or MCP call per block, then a cache. REST calls are paced per minute across parallel runs. A rate limit stops with the reset time; it never spends your MCP budget behind your back. [The limits](#how-figma-integration-works).
|
|
24
34
|
- **QA before review.** `eds block test` does visual regression on the block itself, plus a design↔render diff. `eds block check` covers content and a11y, including preview mocks nested deeper than real EDS markup. There are also `doctor`, loading and security audits.
|
|
@@ -26,6 +36,17 @@ It lives next to `@adobe/aem-cli` (your local dev server) and handles everything
|
|
|
26
36
|
|
|
27
37
|
Proof: the whole example screen (11 blocks) was generated from a scraped page and from Figma exports, screenshotted next to the design, and 163 + 22 real AEM components were migrated. See the [end-to-end test](https://piotrgodycki.github.io/aem-eds-kit/e2e-example.html).
|
|
28
38
|
|
|
39
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/design-vs-block.webp" alt="A Google Stitch hero design next to the EDS block eds generated from it: same layout, type scale, colours and buttons, with placeholder copy" width="100%"></p>
|
|
40
|
+
|
|
41
|
+
<details>
|
|
42
|
+
<summary><strong>The whole screen</strong>: design vs. the 11 generated blocks</summary>
|
|
43
|
+
|
|
44
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/design-vs-page.webp" alt="The full example page design next to the page built from 11 generated EDS blocks" width="100%"></p>
|
|
45
|
+
|
|
46
|
+
Generated blocks ship with placeholder copy (and empty image slots) until authors fill them in; the layout, spacing, type and colours come from the design.
|
|
47
|
+
|
|
48
|
+
</details>
|
|
49
|
+
|
|
29
50
|
## Install
|
|
30
51
|
|
|
31
52
|
```bash
|
|
@@ -70,7 +91,7 @@ eds block from-design "<figma-url>" --name hero
|
|
|
70
91
|
|
|
71
92
|
## Try it in 30 seconds (no Figma account, no token)
|
|
72
93
|
|
|
73
|
-
From inside an EDS project (or
|
|
94
|
+
From inside an EDS project (or clone a fresh one with `eds new demo && cd demo`):
|
|
74
95
|
|
|
75
96
|
```bash
|
|
76
97
|
eds block from-design --sample --name hero --dry-run # see the prompt - zero setup
|
|
@@ -78,19 +99,32 @@ eds block from-design --sample --name hero # generate it with your A
|
|
|
78
99
|
eds block preview hero # see it live in the browser
|
|
79
100
|
```
|
|
80
101
|
|
|
81
|
-
`--sample` uses
|
|
102
|
+
`--sample` uses the **hero of the project's example design**, bundled as an SVG and read straight from disk - **no Figma token, no MCP call, no network**. (`--dry-run` needs no AI agent either - it just prints the prompt.)
|
|
103
|
+
|
|
104
|
+
A real run (Claude Code): the agent's live log, a verification pass over the files it wrote, then a menu to refine, preview or finish.
|
|
105
|
+
|
|
106
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/cli-fd.png" alt="Terminal: eds block from-design --sample (the example hero), showing the design source, the agent's live log, the files it wrote, a verification table and the refine / preview / finish menu" width="760"></p>
|
|
107
|
+
|
|
108
|
+
`eds block preview` serves the block at the design's own widths, with live reload:
|
|
109
|
+
|
|
110
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/block-preview.webp" alt="Browser: the eds block preview harness showing the hero block at 1440 px with a breakpoint dropdown" width="100%"></p>
|
|
82
111
|
|
|
83
|
-
Ready for the real thing?
|
|
112
|
+
Ready for the real thing? The same example design exists as a page you can build every block from, and as a Figma file:
|
|
84
113
|
|
|
85
114
|
```bash
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
--name hero
|
|
115
|
+
# the example page (11 sections: hero, stats, cards, …) - read like a Framer / Stitch page
|
|
116
|
+
eds block from-design "https://piotrgodycki.github.io/aem-eds-kit/example/" --name cards
|
|
89
117
|
```
|
|
90
118
|
|
|
119
|
+
The Figma version is built by the plugin in [`examples/figma-kit`](https://github.com/piotrgodycki/aem-eds-kit/tree/main/examples/figma-kit) (run it once in Figma desktop); then pass any of its frame links.
|
|
120
|
+
|
|
91
121
|
## Interactive mode
|
|
92
122
|
|
|
93
|
-
Run `eds` with no command and it opens an **interactive menu** that stays open between actions (arrows to move, Enter to run, **Esc** to go back - or to quit from the menu itself; Ctrl+C quits anywhere). It walks you through every feature (set up
|
|
123
|
+
Run `eds` with no command and it opens an **interactive menu** that stays open between actions (arrows to move, Enter to run, **Esc** to go back - or to quit from the menu itself; Ctrl+C quits anywhere). It walks you through every feature: new project (clone the boilerplate), set up project, page template, sandbox repo, block from design, migrate component, scaffold UE, empty block, integration, model fields, analytics, structured data, Universal Editor, preview block, pages (preview / publish), audits and Figma MCP.
|
|
124
|
+
|
|
125
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/cli-menu.png" alt="Terminal: the eds interactive menu with Block from design selected" width="560"></p>
|
|
126
|
+
|
|
127
|
+
Most commands are also interactive on their own when you omit arguments - e.g. `eds init`, `eds block from-design` (wizard), `eds migrate component`, `eds scaffold`, `eds integrate`, `eds preview`. Flags and subcommands still work for CI / power users.
|
|
94
128
|
|
|
95
129
|
A full A-Z reference of every command lives on the docs page: **https://piotrgodycki.github.io/aem-eds-kit/docs.html**
|
|
96
130
|
|
|
@@ -99,6 +133,9 @@ A full A-Z reference of every command lives on the docs page: **https://piotrgod
|
|
|
99
133
|
```bash
|
|
100
134
|
eds # interactive menu
|
|
101
135
|
|
|
136
|
+
# Start from the latest boilerplate (DA, Universal Editor or Commerce)
|
|
137
|
+
eds new my-site
|
|
138
|
+
|
|
102
139
|
# Just cloned an EDS boilerplate? Set it up for your authoring model
|
|
103
140
|
eds init
|
|
104
141
|
|
|
@@ -131,7 +168,8 @@ The full path, command by command. This example targets **DA (da.live)** authori
|
|
|
131
168
|
# 1. Install the CLI
|
|
132
169
|
npm i -g aem-eds-kit
|
|
133
170
|
|
|
134
|
-
# 2.
|
|
171
|
+
# 2. Clone the latest boilerplate, then set it up (pick DA, enter org + site)
|
|
172
|
+
eds new my-site && cd my-site
|
|
135
173
|
eds init --authoring da --org my-org --site my-site
|
|
136
174
|
|
|
137
175
|
# 3. Scaffold the Universal Editor config + helper functions
|
|
@@ -160,6 +198,32 @@ Every step is also interactive when you omit the flags - run `eds` for the menu.
|
|
|
160
198
|
|
|
161
199
|
## Commands
|
|
162
200
|
|
|
201
|
+
### `eds new [dir]`
|
|
202
|
+
|
|
203
|
+
Clone the **current EDS boilerplate** into a local folder. No GitHub auth needed, and nothing is created on GitHub (for a repo on GitHub, see [`eds sandbox`](#eds-sandbox)). Choose Document Authoring / DA (`adobe/aem-boilerplate`), Universal Editor / crosswalk (`adobe-rnd/aem-boilerplate-xwalk`), the Adobe Commerce storefront (`hlxsites/aem-boilerplate-commerce`), or any repo or git URL.
|
|
204
|
+
|
|
205
|
+
By default the copy starts a **fresh git history**, with one initial commit naming the boilerplate commit it came from. `--keep-history` keeps the boilerplate's history with its remote named `upstream`, so `git pull upstream main` brings in later boilerplate changes. It refuses a folder that isn't empty, then offers `npm install` and `eds init`, with Universal Editor preselected for the crosswalk boilerplate.
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
eds new # guided
|
|
209
|
+
eds new my-site --yes # DA boilerplate, fresh history
|
|
210
|
+
eds new my-site --ue --keep-history # crosswalk, with an upstream remote
|
|
211
|
+
eds new shop --boilerplate commerce --install
|
|
212
|
+
eds new my-site --remote git@github.com:me/my-site.git
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
| Flag | Description |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `--boilerplate <repo>` | `da` \| `ue` \| `commerce`, `owner/repo` on GitHub, or any git URL / path |
|
|
218
|
+
| `--ue` | The crosswalk / Universal Editor boilerplate |
|
|
219
|
+
| `--ref <ref>` | Branch or tag to clone |
|
|
220
|
+
| `--keep-history` | Keep the boilerplate's history (remote renamed to `upstream`) |
|
|
221
|
+
| `--remote <url>` | Set `origin` to your own repo |
|
|
222
|
+
| `--install` | Run `npm install` after cloning |
|
|
223
|
+
| `--yes` | Skip the guided prompts |
|
|
224
|
+
|
|
225
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/cli-new-picker.png" alt="Terminal: eds new asking for a folder and offering the DA, Universal Editor and Commerce boilerplates" width="660"></p>
|
|
226
|
+
|
|
163
227
|
### `eds init`
|
|
164
228
|
|
|
165
229
|
Adapt a freshly cloned EDS boilerplate to your setup in one interactive wizard. Pick the authoring model - **Universal Editor (crosswalk), DA (da.live), Google Drive or SharePoint** - and `eds` sets the project name (`package.json` + boilerplate placeholders), writes `fstab.yaml` **only when the model needs it** (UE/crosswalk doesn't), scaffolds the crosswalk config + `paths.json` for UE, optionally adds the CI workflow, then walks the **external steps** (AEM Code Sync app, content-source share, Sidekick) as a clickable checklist.
|
|
@@ -171,15 +235,18 @@ By default it also writes, out of the box:
|
|
|
171
235
|
|
|
172
236
|
Opt out with `--no-env` / `--no-xwalk`, or (re)generate either later with `eds scaffold env` / `eds scaffold xwalk`.
|
|
173
237
|
|
|
238
|
+
**Non-interactive (`--yes`).** The project name defaults to the folder name (or `package.json`'s, unless that's still the boilerplate's own). The authoring model is detected from the `fstab.yaml` mountpoint (an AEM author → Universal Editor, `content.da.live` → DA, Google Drive, SharePoint) or a crosswalk `paths.json`, and preselected in the interactive picker. When it can't be told (the DA boilerplate ships no `fstab.yaml`), `--yes` stops with exit 1 and asks for `--authoring`.
|
|
239
|
+
|
|
174
240
|
```bash
|
|
175
241
|
eds init # interactive
|
|
242
|
+
eds init --yes # detect everything (e.g. right after `eds new --ue`)
|
|
176
243
|
eds init --name my-site --authoring da --org my-org --site my-site --yes
|
|
177
244
|
```
|
|
178
245
|
|
|
179
246
|
| Flag | Description |
|
|
180
247
|
|---|---|
|
|
181
248
|
| `--name <name>` | Project name (kebab-case) |
|
|
182
|
-
| `--authoring <model>` | `ue` \| `da` \| `gdrive` \| `sharepoint` |
|
|
249
|
+
| `--authoring <model>` | `ue` \| `da` \| `gdrive` \| `sharepoint` (else detected from `fstab.yaml` / `paths.json`) |
|
|
183
250
|
| `--mountpoint <url>` | Content source URL (document models) |
|
|
184
251
|
| `--org <org>` / `--site <site>` | DA org / site (`--authoring da`) |
|
|
185
252
|
| `--no-ci` | Skip the GitHub Actions workflow |
|
|
@@ -216,18 +283,21 @@ Spin up and tear down **disposable EDS sandbox repos** on GitHub - a rapid, thro
|
|
|
216
283
|
eds sandbox login # authorize GitHub (device flow or token)
|
|
217
284
|
eds sandbox new my-test # guided: boilerplate, visibility, Code Sync, eds init
|
|
218
285
|
eds sandbox new my-test --ue --private --yes
|
|
286
|
+
eds sandbox new shop --boilerplate hlxsites/aem-boilerplate-commerce # any template repo
|
|
219
287
|
eds sandbox list # your sandboxes (tagged eds-sandbox) + preview URLs
|
|
220
288
|
eds sandbox rm my-test # delete it (with confirmation)
|
|
221
289
|
```
|
|
222
290
|
|
|
223
|
-
`sandbox new` creates the repo from a boilerplate (Document Authoring `adobe/aem-boilerplate
|
|
291
|
+
`sandbox new` creates the repo from a boilerplate (Document Authoring `adobe/aem-boilerplate`, Universal Editor `adobe-rnd/aem-boilerplate-xwalk`, or any template repo with `--boilerplate <owner/repo>`) via the GitHub API, clones it, tags it `eds-sandbox`, then walks you through opening the AEM Code Sync install page and running `eds init`. The preview URL is `https://main--<repo>--<owner>.aem.page/`.
|
|
224
292
|
|
|
225
293
|
Sandboxes are **throwaway test repos** - stand one up to debug or try an integration, then delete it; they work fine on a personal account. Two safety guarantees:
|
|
226
294
|
|
|
227
295
|
- **Never overwrites an existing repo.** `sandbox new` checks first and refuses if `<owner>/<name>` already exists (and the GitHub template API never clobbers either way).
|
|
228
296
|
- **Least privilege.** Scope the token to just your sandboxes - a fine-grained token limited to one repo, or a dedicated sandbox org used via `--org`. `eds sandbox login` links you straight to the token page with the minimal permissions. See the [Secure GitHub sandboxes guide](https://piotrgodycki.github.io/aem-eds-kit/secure-github-sandboxes.html).
|
|
229
297
|
|
|
230
|
-
The token is stored owner-only (mode `0600`) in `~/.eds/github.json`; `eds sandbox logout` removes it. `list` only ever shows `eds-sandbox` repos and `rm` deletes only the named repo, with confirmation.
|
|
298
|
+
The token is stored owner-only (mode `0600`) in `~/.eds/github.json`; `eds sandbox logout` removes it. `list` only ever shows `eds-sandbox` repos and `rm` deletes only the named repo (under `--org <org>` when it lives in an org), with confirmation.
|
|
299
|
+
|
|
300
|
+
Just want the code on your machine, no GitHub repo? Use [`eds new`](#eds-new-dir).
|
|
231
301
|
|
|
232
302
|
### `eds migrate component [dir]`
|
|
233
303
|
|
|
@@ -244,6 +314,8 @@ eds migrate component ./ui.apps/.../apps/wknd/components/teaser \
|
|
|
244
314
|
--super-root ../aem-core-wcm-components/content/src/content/jcr_root # proxy → Core Component dialog
|
|
245
315
|
```
|
|
246
316
|
|
|
317
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/cli-mig.png" alt="Terminal: eds migrate component on the WKND teaser proxy component; the dialog is inherited from the Core Components teaser and its 13 fields are mapped to Universal Editor field types" width="760"></p>
|
|
318
|
+
|
|
247
319
|
Dialogs map cleanly because Granite's `sling:resourceType` set is finite. The most faithful CSS actually comes from the **rendered page** (resolves LESS vars + cascade) - that capture lands in a later phase; for now the clientlib source gets you most of the way.
|
|
248
320
|
|
|
249
321
|
### `eds track block <name>`
|
|
@@ -306,9 +378,9 @@ The generated `_<name>.json` uses the EDS block-plugin (xwalk) format (`definiti
|
|
|
306
378
|
|
|
307
379
|
### `eds block from-design [design-url]`
|
|
308
380
|
|
|
309
|
-
Translates a design - **a Figma URL, a Framer / Google Stitch page, or a local SVG/PNG export** - into an EDS block. Run with **no URL** for a step-by-step wizard (design source, name, link, content source, UE model, screenshot, run mode). It builds a prompt with EDS conventions + your project's design tokens and hands it to your AI agent (Claude Code, Cursor, or
|
|
381
|
+
Translates a design - **a Figma URL, a Framer / Google Stitch page, or a local SVG/PNG export** - into an EDS block. Run with **no URL** for a step-by-step wizard (design source, name, link, content source, UE model, screenshot, run mode). It builds a prompt with EDS conventions + your project's design tokens and hands it to your AI agent (Claude Code, Cursor or Codex, or a [local model](#local-models-ollama-omlx)). *(This was `from-figma` before it went design-agnostic; Figma is the most battle-tested source and stays pixel-perfect.)*
|
|
310
382
|
|
|
311
|
-
**Figma vs. web sources.** Figma paints to a WebGL canvas, so it's read through the **REST API** (with a token) or **MCP**. Framer
|
|
383
|
+
**Figma vs. web sources.** Figma paints to a WebGL canvas, so it's read through the **REST API** (with a token) or **MCP**. Framer, Google Stitch and **any other web page** (a live site you're rebuilding, an HTML mock-up) render **real HTML**, so `eds` **scrapes** them with headless Chromium — reading computed layout, typography, colours and geometry straight off the page (no token, no MCP). On a page with several sections, the block is built from the one matching `--name`: try `eds block from-design https://piotrgodycki.github.io/aem-eds-kit/example/ --name cards`. Canva and Sketch are canvas/image-based and aren't scrapeable — export a frame and pass it as a local SVG/PNG. The provider is detected from the URL (Figma, Framer, Stitch, else a web page), or set with `--provider`.
|
|
312
384
|
|
|
313
385
|
**Gated sources (`--auth`).** A Google Stitch project (and a private Framer page) sits behind a login, so an anonymous scrape only sees the sign-in shell. Pass `--auth` and `eds` opens a **headed** browser once — you log in by hand, it saves the session, and every later scrape reuses it. The session (cookies/localStorage) is stored owner-only under `~/.eds/auth/<provider>.json`; re-login with `--auth-refresh`. (The saved session is a secret — it's never written to the repo.)
|
|
314
386
|
|
|
@@ -340,18 +412,20 @@ eds block from-design # interactive wizard
|
|
|
340
412
|
eds block from-design "<figma-url>" --name hero # non-interactive (REST if a token is set, else MCP)
|
|
341
413
|
eds block from-design "<framer-url>" --name hero # Framer/Stitch → scraped with headless Chromium
|
|
342
414
|
eds block from-design "<stitch-url>" --name hero --auth # gated source → log in once, reuse the session
|
|
415
|
+
eds block from-design "https://piotrgodycki.github.io/aem-eds-kit/example/" --name cards # any web page, one section
|
|
343
416
|
eds block from-design ./hero.svg --name hero # from a local export (no network)
|
|
344
|
-
eds block from-design --sample --name hero # bundled
|
|
417
|
+
eds block from-design --sample --name hero # bundled example hero (no token, no MCP)
|
|
345
418
|
eds block from-design "<figma-url>" --dry-run # just build the prompt
|
|
346
419
|
```
|
|
347
420
|
|
|
348
421
|
| Flag | Description |
|
|
349
422
|
|---|---|
|
|
350
423
|
| `--name <name>` | Override the inferred block name |
|
|
351
|
-
| `--provider <type>` | Design source: `figma` \| `framer` \| `stitch` (else detected from the URL) |
|
|
424
|
+
| `--provider <type>` | Design source: `figma` \| `framer` \| `stitch` \| `web` (else detected from the URL) |
|
|
352
425
|
| `--source <type>` | Content source: `document` \| `ue` \| `cf` \| `mixed` (`cf` / `mixed` default to the `sonnet` model) |
|
|
353
426
|
| `--widths <list>` | Design frame widths for preview breakpoints (e.g. `390,768,1440`) |
|
|
354
|
-
| `--agent <type>` | Force `claude` \| `cursor` \| `codex` \| `none` (a prompt too large for one argument reaches Cursor / Codex as its file) |
|
|
427
|
+
| `--agent <type>` | Force `claude` \| `cursor` \| `codex` \| `ollama` \| `omlx` \| `local` \| `none` (a prompt too large for one argument reaches Cursor / Codex as its file; see [Local models](#local-models-ollama-omlx)) |
|
|
428
|
+
| `--model <name>` | Model to run: a Claude alias / id, or a local model such as `qwen2.5-coder:14b` |
|
|
355
429
|
| `--dry-run` | Build the prompt only |
|
|
356
430
|
| `--no-ue-model` | Skip the Universal Editor model |
|
|
357
431
|
| `--screenshot` | Add a screenshot MCP call for a pixel check (opt-in — costs a call) |
|
|
@@ -359,7 +433,7 @@ eds block from-design "<figma-url>" --dry-run # just build the prompt
|
|
|
359
433
|
| `--auth` | Scrape with a logged-in session (Framer/Stitch): log in once, reuse it |
|
|
360
434
|
| `--auth-refresh` | Force a fresh scrape login even if a session is saved |
|
|
361
435
|
| `--refresh` | Ignore the cached snapshot and re-fetch |
|
|
362
|
-
| `--sample` | Use the bundled
|
|
436
|
+
| `--sample` | Use the bundled sample design, the example file's hero (no URL, token or MCP) |
|
|
363
437
|
| `--serve` | Auto-start the live preview (non-interactive runs only) |
|
|
364
438
|
| `--yes` | Skip confirmation prompts |
|
|
365
439
|
|
|
@@ -376,7 +450,7 @@ The generated block records the **design's frame widths** in its `.eds-meta.json
|
|
|
376
450
|
### `eds figma setup`
|
|
377
451
|
|
|
378
452
|
Interactive wizard that:
|
|
379
|
-
1. Detects installed AI agents (Claude Code, Cursor, Codex)
|
|
453
|
+
1. Detects installed AI agents (Claude Code, Cursor, Codex) and running local model servers (Ollama, oMLX)
|
|
380
454
|
2. Checks if Figma MCP is configured for your agent
|
|
381
455
|
3. Shows install commands if not
|
|
382
456
|
4. Saves preferences to `~/.eds/config.json`
|
|
@@ -403,6 +477,13 @@ eds block preview hero --widths 375,768,1280 # custom breakpoints
|
|
|
403
477
|
eds block preview hero --port 9000 --no-open
|
|
404
478
|
```
|
|
405
479
|
|
|
480
|
+
- A dropdown switches the block between breakpoints inside an `<iframe>`, so the block's media queries fire against the chosen width - a **width-honest** comparison that isn't distorted by your monitor size.
|
|
481
|
+
- Breakpoints come from the block's `.eds-meta.json` (`breakpoints`, marking which widths have a real Figma frame → pixel-perfect) and fall back to `375 / 768 / 1280` or `--widths`.
|
|
482
|
+
- If the block has a `.eds-meta.json` with a Figma source, an **Open in Figma** link is shown.
|
|
483
|
+
- Authored sample content is read from `blocks/<name>/_<name>.preview.html` if present; otherwise a placeholder is used (and the chrome tells you to add one).
|
|
484
|
+
|
|
485
|
+
> Not to be confused with `eds preview [paths...]` (lower down), which previews **pages** via the AEM Admin API.
|
|
486
|
+
|
|
406
487
|
### `eds block test [name]` · `eds block check [name]`
|
|
407
488
|
|
|
408
489
|
Two deterministic QA passes over a block's **rendered** DOM (no agent) - one block, or **all** of them when you omit the name. Both render the block in headless Chromium (Playwright), so install the browser once: `npx playwright install chromium`. Wire them into CI next to the audits - both exit non-zero on failure.
|
|
@@ -417,6 +498,11 @@ eds block test hero --design # rendered block vs its Figma design imag
|
|
|
417
498
|
eds block test --threshold 0.02 # allow 2% changed pixels
|
|
418
499
|
```
|
|
419
500
|
|
|
501
|
+
A CSS change that moved the hero's buttons and text, caught at 1440 px, with the diff image it wrote:
|
|
502
|
+
|
|
503
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/cli-test.png" alt="Terminal: eds block test hero reporting 2.48% changed pixels at 1440px and the diff PNG path" width="760"></p>
|
|
504
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/visual-diff.webp" alt="Diff image: the changed pixels of the hero block highlighted in red and yellow" width="760"></p>
|
|
505
|
+
|
|
420
506
|
| Flag | Description |
|
|
421
507
|
|---|---|
|
|
422
508
|
| `--update` | (Re)write baseline screenshots instead of comparing |
|
|
@@ -433,6 +519,8 @@ eds block check hero # one block
|
|
|
433
519
|
eds block check --strict # fail on warnings too
|
|
434
520
|
```
|
|
435
521
|
|
|
522
|
+
<p align="center"><img src="https://raw.githubusercontent.com/piotrgodycki/aem-eds-kit/main/.github/assets/readme/cli-check.png" alt="Terminal: eds block check hero warning that the preview mock nests cell content one div deeper than EDS markup" width="760"></p>
|
|
523
|
+
|
|
436
524
|
| Flag | Description |
|
|
437
525
|
|---|---|
|
|
438
526
|
| `--strict` | Fail on warnings too, not just errors |
|
|
@@ -473,28 +561,23 @@ eds integrate # interactive
|
|
|
473
561
|
eds integrate gtm # gtm · ga4 · chat · cookiebot · custom
|
|
474
562
|
```
|
|
475
563
|
|
|
476
|
-
|
|
477
|
-
- Breakpoints come from the block's `.eds-meta.json` (`breakpoints`, marking which widths have a real Figma frame → pixel-perfect) and fall back to `375 / 768 / 1280` or `--widths`.
|
|
478
|
-
- If the block has a `.eds-meta.json` with a Figma source, an **Open in Figma** link is shown.
|
|
479
|
-
- Authored sample content is read from `blocks/<name>/_<name>.preview.html` if present; otherwise a placeholder is used (and the chrome tells you to add one).
|
|
480
|
-
|
|
481
|
-
> Not to be confused with `eds preview <paths...>` (lower down), which previews **pages** via the AEM Admin API.
|
|
564
|
+
### `eds preview [paths...]`
|
|
482
565
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
Preview pages via the AEM Admin API (`admin.hlx.page`).
|
|
566
|
+
Preview pages via the AEM Admin API (`admin.hlx.page`). Run it with no paths for a wizard (pick the action, the paths and the org / site / ref).
|
|
486
567
|
|
|
487
568
|
```bash
|
|
569
|
+
eds preview # wizard
|
|
488
570
|
eds preview /index
|
|
489
571
|
eds preview /blog/my-post /about
|
|
490
572
|
eds preview /index --org my-org --site my-repo --ref main
|
|
491
573
|
```
|
|
492
574
|
|
|
493
|
-
### `eds publish
|
|
575
|
+
### `eds publish [paths...]`
|
|
494
576
|
|
|
495
|
-
Publish pages to live via the AEM Admin API.
|
|
577
|
+
Publish pages to live via the AEM Admin API (a wizard when run with no paths).
|
|
496
578
|
|
|
497
579
|
```bash
|
|
580
|
+
eds publish # wizard
|
|
498
581
|
eds publish /index
|
|
499
582
|
eds publish /blog/my-post /about
|
|
500
583
|
```
|
|
@@ -571,7 +654,8 @@ The design is fetched **once** into a cached snapshot, then the agent generates
|
|
|
571
654
|
┌─ local SVG/PNG ─┐
|
|
572
655
|
├─ cache hit ──────┤ design.json ┌─────────────┐ block files
|
|
573
656
|
design reference ──┼─ Figma REST ─────┼───→ (cached) ───────→│ Claude Code │ ───────────────→ repo
|
|
574
|
-
(url / file)
|
|
657
|
+
(url / file) ├─ web scrape ─────┤ snapshot │ Cursor/Codex│
|
|
658
|
+
└─ Figma MCP ──────┘ │ Ollama/oMLX │
|
|
575
659
|
(1 call, agent dumps to cache) └─────────────┘
|
|
576
660
|
```
|
|
577
661
|
|
|
@@ -587,6 +671,35 @@ The prompt includes:
|
|
|
587
671
|
- Lighthouse performance requirements + a single structural self-verification pass
|
|
588
672
|
- Output file structure
|
|
589
673
|
|
|
674
|
+
## Local models (Ollama, oMLX)
|
|
675
|
+
|
|
676
|
+
Keep designs and code on your machine: `eds block from-design` can run a local model instead of Claude Code / Cursor / Codex.
|
|
677
|
+
|
|
678
|
+
```bash
|
|
679
|
+
ollama pull qwen2.5-coder:14b && ollama serve # or: omlx start (Apple Silicon)
|
|
680
|
+
eds block from-design "<framer-url>" --name hero --agent ollama
|
|
681
|
+
eds block from-design ./hero.png --name hero --agent ollama --model qwen2.5vl:7b # PNG → vision model
|
|
682
|
+
eds block from-design ./hero.svg --name hero --agent omlx
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
| Agent | Server (default) | API |
|
|
686
|
+
|---|---|---|
|
|
687
|
+
| `ollama` | `http://127.0.0.1:11434` | native `/api/chat` (so `num_ctx` can be raised) |
|
|
688
|
+
| `omlx` | `http://127.0.0.1:8000/v1` | OpenAI-compatible `/v1/chat/completions` |
|
|
689
|
+
| `local` | `local.baseUrl` | any OpenAI-compatible server (LM Studio, llama.cpp, vLLM…) |
|
|
690
|
+
|
|
691
|
+
- **No tools, so the CLI does the I/O.** A local model can't read files or call MCP. `eds` sends the whole prompt - a scraped page or Figma REST spec embedded, an SVG export inlined, a PNG / JPG attached as an image - and asks for every file in a `=== FILE: … ===` format. It then writes those files itself, **only inside `blocks/<name>/`**. The raw reply is kept in `tmp/eds-cli/local-reply-*.md`.
|
|
692
|
+
- **Figma needs REST or an export.** A Figma link without a token would need MCP, which a local model can't call: set `FIGMA_TOKEN`, or export the frame as PNG/SVG.
|
|
693
|
+
- **Model.** `--model`, else `local.model`, else a coder model the server has (`*coder*`, Codestral/Devstral, Qwen, DeepSeek…). A PNG/JPG design needs a vision model.
|
|
694
|
+
- **Context.** A design prompt is ~20-40k tokens. Ollama is asked for `local.contextTokens` (default **32768**, raised automatically when the prompt needs more); for other servers set the context length on the server. `eds` warns when the prompt won't fit.
|
|
695
|
+
- **Auto-detect.** With no CLI agent installed, `eds` uses a running Ollama or oMLX server. Refine passes work too: the model gets the block's current files and returns the changed ones.
|
|
696
|
+
|
|
697
|
+
```json
|
|
698
|
+
{ "agent": "ollama", "local": { "model": "qwen2.5-coder:14b", "contextTokens": 49152 } }
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
`local.baseUrl` points at a different host or port, and `local.apiKey` is sent as a bearer token for servers that want one.
|
|
702
|
+
|
|
590
703
|
## Configuration
|
|
591
704
|
|
|
592
705
|
Priority: CLI flags → env vars → `.edsrc.json` (project) → `~/.eds/config.json` (global)
|
|
@@ -596,10 +709,11 @@ Priority: CLI flags → env vars → `.edsrc.json` (project) → `~/.eds/config.
|
|
|
596
709
|
{
|
|
597
710
|
"agent": "claude",
|
|
598
711
|
"model": "haiku",
|
|
599
|
-
"figma": { "token": "figd_…", "restPerMinute": 10 }
|
|
712
|
+
"figma": { "token": "figd_…", "restPerMinute": 10 },
|
|
713
|
+
"local": { "model": "qwen2.5-coder:14b", "contextTokens": 49152 }
|
|
600
714
|
}
|
|
601
715
|
```
|
|
602
|
-
`model` sets the block-generation model (default: fastest / Haiku). `figma.token` (or the `FIGMA_TOKEN` env var) enables the REST fetch path — a Personal Access Token with scope `file_content:read`. Tokens are secrets; keep them out of the repo.
|
|
716
|
+
`agent` picks the agent (`claude`, `cursor`, `codex`, `ollama`, `omlx`, `local`); `model` sets the block-generation model (default: fastest / Haiku). `local.*` configures a [local model](#local-models-ollama-omlx). `figma.token` (or the `FIGMA_TOKEN` env var) enables the REST fetch path — a Personal Access Token with scope `file_content:read`. Tokens are secrets; keep them out of the repo.
|
|
603
717
|
|
|
604
718
|
`figma.restPerMinute` paces Figma REST calls across every `eds` run in the project (they share `tmp/eds-cli/figma-rest-calls.json`), so a batch of blocks waits for a free slot instead of hitting a 429. Default **10** (Tier 1, Dev / Full seat on Professional); use 15 on Organization, 20 on Enterprise. On Starter or with a View / Collab seat the cap is monthly (20), so pacing can't help there.
|
|
605
719
|
|
|
@@ -620,13 +734,13 @@ Priority: CLI flags → env vars → `.edsrc.json` (project) → `~/.eds/config.
|
|
|
620
734
|
|---|---|
|
|
621
735
|
| `--verbose` | Debug-level output |
|
|
622
736
|
| `--quiet` | Errors only |
|
|
623
|
-
| `--json` | Machine-readable JSON output |
|
|
737
|
+
| `--json` | Machine-readable JSON output (`doctor`, `audit loading`, `audit security`, `block list`) |
|
|
624
738
|
| `--no-color` | Disable colors (also respects `NO_COLOR` env) |
|
|
625
739
|
|
|
626
740
|
## Development
|
|
627
741
|
|
|
628
742
|
```bash
|
|
629
|
-
git clone
|
|
743
|
+
git clone https://github.com/piotrgodycki/aem-eds-kit.git && cd aem-eds-kit
|
|
630
744
|
npm install
|
|
631
745
|
```
|
|
632
746
|
|
|
@@ -698,11 +812,21 @@ Tests use fixtures in `tests/fixtures/` - a sample EDS project and recorded Figm
|
|
|
698
812
|
|
|
699
813
|
## Roadmap
|
|
700
814
|
|
|
701
|
-
|
|
702
|
-
- **
|
|
703
|
-
- **
|
|
704
|
-
- **
|
|
705
|
-
|
|
815
|
+
**Next**
|
|
816
|
+
- **Previews that look like the design.** The preview gets the design's real copy and images, so it matches 1:1; the block itself still reads authored content.
|
|
817
|
+
- **A self-check against the design.** Render the block, compare it with the Figma frame or the page, and fix what differs in a second pass.
|
|
818
|
+
- **Every breakpoint.** Read the design at mobile, tablet and desktop widths, not just one.
|
|
819
|
+
|
|
820
|
+
**Then**
|
|
821
|
+
- **Whole screens in one go.** Every section of a frame or page becomes a block, plus the page that puts them together.
|
|
822
|
+
- **Blocks that follow the design.** When the design changes, update the existing block instead of regenerating it.
|
|
823
|
+
- **Design tokens for the project.** Figma Variables become the CSS custom properties in `styles.css`.
|
|
824
|
+
|
|
825
|
+
**Later**
|
|
826
|
+
- **Deeper AEM migration.** HTL logic ported to `decorate()`, CSS taken from the rendered page, whole pages migrated.
|
|
827
|
+
- **Performance in the loop.** Lighthouse and real-user data (RUM) checked for every block.
|
|
828
|
+
|
|
829
|
+
Something missing? [Open an issue](https://github.com/piotrgodycki/aem-eds-kit/issues): the roadmap follows what people need.
|
|
706
830
|
|
|
707
831
|
## Trademarks & affiliation
|
|
708
832
|
|