Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/tomevault-io/tomes --skill build-content-from-figma명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
> Use when this capability is needed.
Use when writing kernel, account, or note MASM code that reads from or writes to the advice provider (advice stack / advice map) — validate advice data.
Use when writing a Rust test that exercises a failure path or a MASM test that expects a `panic` / `assert` — assert on the specific expected error variant or error code.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | build-content-from-figma |
| description | > Use when this capability is needed. |
You are creating an authored HTML document for the C2 design system by extracting content from Figma designs. The document follows the standard block authoring pattern and is uploaded to DA (Document Authoring) for publishing via Adobe EDS.
Critical rules
- Assets are downloaded from Figma locally, then uploaded directly to the DA admin API via
curl POSTtoadmin.da.live/source/...with multipart form data.- Block content is authored as a
<table>(seereferences/authoring-pattern.md);section-metadataandmetadataremain div-based.- Never embed images as base64 in DA HTML.
- The HTML references assets using their final
content.da.liveURLs (computed from the DA destination and the shadow folder convention). Since we upload assets ourselves, we know the exact paths upfront.- Typography tokens from Figma (
--s2a-typography-*) determine heading levels, body sizes, and eyebrow classification.- Viewport-specific content follows the inheritance model: only include what changes per viewport. Omit viewports and columns that are identical to a lower viewport.
- Link URLs use
https://www.adobe.com/as a placeholder. Link display text must match Figma.
Do not load these upfront. Each phase tells you which file to read when it becomes relevant.
| File | Purpose |
|---|---|
authoring-pattern.md | HTML div structure for DA block authoring: document skeleton, viewport rows, content columns, media placement, complete examples. |
token-mapping.md | Maps --s2a-typography-* Figma tokens to heading levels (h1-h4), body sizes (lg, md, sm, xs), and eyebrow classification. Includes fallback heuristics. |
| File | Purpose |
|---|---|
figma-content-extractor.md | Extracts structured content (text, media, tokens) from a single Figma frame. Run once per viewport. |
Collect all inputs before starting extraction work.
| Input | Required | Example |
|---|---|---|
| Figma URL(s) | At least one | One URL per viewport (mobile, tablet, desktop) |
| DA destination (org, repo, path) | Yes | adobe / my-repo / docs/my-page.html |
Ask which viewport each Figma URL corresponds to. Valid viewports:
If only one URL is provided, the document has no viewport variations.
Ask the user for Figma frame URL(s). Each URL corresponds to a viewport. At minimum one frame is required.
For each Figma URL, use Figma MCP get_metadata to inspect
the frame name. Look for a recognizable block name in the frame
label or parent component name (e.g. "aside", "marquee", "brick",
"media", "editorial-card").
Present the suggested name and ask the user to confirm or provide
an alternative. This name becomes the class on the block's outer
<div>.
STOP: Do NOT proceed to Phase 2 until the user explicitly confirms the block name. If the user provides a different name, use theirs. If they do not respond, wait.
Ask for:
adobe)my-site)docs/my-page.html)The media folder is derived automatically in Phase 4c using the dot-prefixed shadow folder convention.
Block name: <name>
Viewports: Mobile [check] | Tablet [check/cross] | Desktop [check/cross]
DA target: <org>/<repo>/<path>
Media folder: <org>/<repo>/<media-folder>/
Wait for user confirmation.
Load references/token-mapping.md now.
For each provided Figma frame, load agents/figma-content-extractor.md
and follow its procedure. If multiple frames are provided, run
extractions in parallel.
Provide each extraction with:
Each extraction returns:
Compare extracted content across viewports to determine what needs explicit authoring vs what can be inherited.
Viewports inherit upward: mobile -> tablet -> desktop. See
references/authoring-pattern.md for the full inheritance table
and partial viewport HTML patterns.
For each viewport pair (mobile->tablet, tablet->desktop), compare:
Element | Mobile | Tablet | Desktop
---------------------------------------------------------
Icon | sparkle.svg | = (inherit) | = (inherit)
Eyebrow | "New" | = (inherit) | "Updated"
Heading (h3) | "Get started" | = (inherit) | "Get started today"
Body (body-md) | "Lorem..." | = (inherit) | "Different text..."
Links | 2 links | = (inherit) | 1 link
Background | #1a1a1a | gradient | gradient
Foreground | hero.png | = (inherit) | hero-wide.png
Viewport sections needed: Mobile + Tablet (bg only) + Desktop
Check the body size from each viewport's extraction. body-md is
the default and needs no variant. body-sm or body-lg must be
declared.
Same body size across all viewports: add it as a variant on the block header.
aside + body-sm → <p>aside (body-sm)</p> in the header rowaside + body-lg → <p>aside (body-lg)</p> in the header rowBody size differs per viewport: declare the base (mobile) size on the block header, then override in the viewport row.
<p>aside</p><tr><td colspan="2"><p>Desktop-viewport (body-lg)</p></td></tr><p>aside (body-sm)</p><tr><td colspan="2"><p>Tablet-viewport (body-lg)</p></td></tr>Variants are comma-separated inside parentheses in both the block header and viewport rows; they are text content parsed at render time.
Wait for user confirmation of the diff analysis.
Collect all Figma asset URLs from Phase 2 and download them locally. This is required, not optional. We upload assets directly to the DA admin API, so they must exist on disk first.
Critical constraints
- No compression, no resizing, no Python scripts. DA and EDS handle image optimization.
- Never read image data into context. Do not use the Read tool on image files. Do not
catthem. Do not print base64 output to inspect it.
From the Phase 2 extraction output, collect every Figma asset URL:
Deduplicate: if the same asset appears across viewports (e.g. a shared icon), include it only once.
Download each Figma asset to a local folder. Use descriptive
filenames with proper extensions (e.g. bg-mobile.png,
adobe-firefly-icon.svg). Figma MCP asset URLs serve files
without extensions, so you must determine the type yourself.
mkdir -p /tmp/figma-media/<page-name>
curl -sL "<figma-asset-url>" -o /tmp/figma-media/<page-name>/<filename>
After downloading, verify the file type:
file /tmp/figma-media/<page-name>/<filename>
Common types from Figma:
SVG Scalable Vector Graphics image → use .svg extensionPNG image data → use .png extensionJPEG image data → use .jpg extensionIcons in Figma are almost always multi-layer (background +
symbol/text). get_design_context decomposes them into separate
per-layer asset URLs, each incomplete. Do not use individual
layer asset URLs for icons.
Instead, export the composite SVG via the Figma Plugin API:
// use_figma: Export icon node as composite SVG
const node = await figma.getNodeByIdAsync('<icon-node-id>');
const svgBytes = await node.exportAsync({ format: 'SVG' });
const svgString = String.fromCharCode(...svgBytes);
return svgString;
Save the returned SVG content to a local .svg file. Then:
POST admin.da.live/source/<org>/<repo>/<parent-path>/<icon-name>.svg.POST admin.hlx.page/preview/<org>/<repo>/main/<parent-path>/<icon-name>.svg.aem.page preview URL in the HTML as
both the href and the display text of the icon <a> tag:
<p><a href="https://main--<repo>--<org>.aem.page/<path>/<icon>.svg">https://main--<repo>--<org>.aem.page/<path>/<icon>.svg</a></p>
Since we upload assets directly, compute the final
content.da.live URLs upfront. Use the dot-prefixed shadow
folder convention:
https://content.da.live/<org>/<repo>/<parent-path>/.<page-name>/<filename>
Example: page at homepage/drafts/<your-ldap>/my-block.html
stores media at:
https://content.da.live/<org>/<repo>/homepage/drafts/<your-ldap>/.my-block/bg-mobile.png
These URLs go directly into the HTML in Phase 5.
Solid colors, gradients, and semi-transparent values are not assets. They are placed as text in the media column:
rgb(255 255 255 / 0)#1a1a1alinear-gradient(135deg, #1a1a1a, #2d2d2d)Load references/authoring-pattern.md now.
The block is authored as an explicit <table> so that media can
stack in the right column while the text column spans via rowspan.
The surrounding section-metadata and metadata sections remain
div-based.
<body>
<header></header>
<main>
<div>
<table>
<tbody>
<tr><td colspan="2"><p>block-name (variant1, variant2)</p></td></tr>
<!-- viewport and content rows -->
</tbody>
</table>
<div class="section-metadata">
<div>
<div>style</div>
<div>container, wide</div>
</div>
</div>
</div>
<div>
<div class="metadata">
<div>
<div>foundation
c2
The first row of the block table is the header: a single
<td colspan="2"> containing <p>block-name (variant1, variant2)</p>.
Variants go in parentheses, comma-separated. If there are no
variants, just <p>block-name</p>.
The section-metadata block is placed in the same section as
the content block (same parent <div>, no --- separator). It
sets style: container, wide for the section layout.
The metadata section with foundation: c2 is required for C2
blocks. Without it, the EDS block loader will not resolve blocks
from libs/c2/blocks/ and the block JS/CSS will fail to load.
No viewport variations (single frame, or all viewports identical): the header row is followed directly by the content row(s); no viewport rows.
With viewport variations: add viewport rows and content rows
per the authoring pattern. Only include viewports that differ from
their parent. Each viewport row is a single <td colspan="2">
containing the viewport keyword.
For each viewport section:
Left column text cell (use rowspan="N" where N = number of
stacked media sub-rows on the right; omit rowspan when N=1):
<p><a href="<aem.page-preview-url>"><aem.page-preview-url></a></p> (if present). Both href and display text are the preview URL. See Phase 4b for SVG icon upload details.<p>eyebrow text</p> (if present)<hN>text</hN> where N is from token mapping. Add
<strong> inside if the Figma text is bold.<p>text</p><a> based on its CTA style:
<strong><a href="https://www.adobe.com/">text</a></strong><em><a href="https://www.adobe.com/">text</a></em><a href="https://www.adobe.com/">text</a>Right column media cells (one <td> per media element, each in
its own <tr> after the first):
<td><td><picture><img src="<content.da.live-url>" alt="..."></picture></td>Order in the right column: background first, foreground second,
then any additional media. The first media sub-row shares the <tr>
with the text cell; every subsequent media sub-row is its own <tr>
containing only the right <td>.
Write the HTML file to the upload folder, mirroring the DA path:
/tmp/da-upload/<da-path>/<page-name>.html
Example: /tmp/da-upload/homepage/drafts/<your-ldap>/my-page.html
Show the constructed HTML to the user and ask for confirmation before proceeding to upload.
Upload images and HTML directly to the DA admin API. No intermediate tools needed.
All curl commands in Phases 6 and 7 use:
TOKEN=$(da-auth-helper token 2>/dev/null)
Present the upload plan and ask:
DA upload:
HTML: /tmp/da-upload/<da-path>/<page-name>.html
Assets: <N> images in /tmp/figma-media/<page-name>/
Target: <org>/<repo>
Ready to upload?
Wait for user confirmation before proceeding.
Verify da-auth-helper is installed and can provide a token:
da-auth-helper token >/dev/null 2>&1 && echo "Token OK" || echo "No token"
If the command fails, instruct the user to:
npm install -g github:adobe-rnd/da-auth-helperda-auth-helper login (opens browser for Adobe IMS; choose the Skyline profile when prompted)da-auth-helper tokenWait for the user to confirm before continuing. The token is
cached at ~/.aem/da-token.json and refreshed automatically
when it expires.
Upload each image to the shadow folder via the DA admin API.
Use POST with multipart form data. Run uploads in parallel.
curl -s -w "\n%{http_code}" -X POST \
"https://admin.da.live/source/<org>/<repo>/<parent-path>/.<page-name>/<filename>" \
-H "Authorization: Bearer $TOKEN" \
-F "data=@/tmp/figma-media/<page-name>/<filename>;type=<mime-type>"
MIME types:
.png → image/png.jpg / .jpeg → image/jpeg.svg → image/svg+xml.webp → image/webpExpect 201 Created for each file. If you get 401, the token has expired; ask the user to refresh it.
Upload the HTML file to DA:
curl -s -w "\n%{http_code}" -X POST \
"https://admin.da.live/source/<org>/<repo>/<da-path>/<page-name>.html" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: text/html" \
--data-binary @/tmp/da-upload/<da-path>/<page-name>.html
Expect 200 OK or 201 Created.
After uploading, verify images are accessible:
curl -s -o /dev/null -w "%{http_code}" \
"https://content.da.live/<org>/<repo>/<parent-path>/.<page-name>/<filename>" \
-H "Authorization: Bearer $TOKEN"
Expect 200 for each image.
On success: report the DA edit URL:
https://da.live/edit#/<org>/<repo>/<da-path>/<page-name>On failure:
da-auth-helper login (choose the Skyline profile).After a successful upload, ask the user whether they want to preview and publish the document.
Document uploaded. Would you like to preview and publish? (y/n)
If the user declines, skip to Phase 8.
Check whether the DA file path contains /drafts/.
Path contains /drafts/: safe to proceed. Continue to 7c.
Path does NOT contain /drafts/:
Present this warning and wait for explicit confirmation:
⚠️ You're about to preview and publish a document on production.
Are you sure you want to proceed? (y/n)
If the user declines, skip to Phase 8.
STOP: Do NOT call the preview or publish APIs without passing this check. This guardrail is mandatory and cannot be bypassed, even if the user already confirmed the upload in Phase 6a. The two confirmations serve different purposes.
POST to the EDS admin API to generate a preview:
curl -s -w "\n%{http_code}" -X POST \
"https://admin.hlx.page/preview/<org>/<repo>/main/<da-path>/<page-name>" \
-H "Authorization: Bearer $TOKEN"
Expect 200 OK. On success, report the preview URL:
Preview: https://main--<repo>--<org>.aem.page/<da-path>/<page-name>
POST to the EDS admin API to publish. If the document contains SVG icons (uploaded and previewed in Phase 4b), publish those first, then publish the document.
# Publish each SVG icon (if any)
curl -s -w "\n%{http_code}" -X POST \
"https://admin.hlx.page/live/<org>/<repo>/main/<parent-path>/<icon-name>.svg" \
-H "Authorization: Bearer $TOKEN"
# Publish the document
curl -s -w "\n%{http_code}" -X POST \
"https://admin.hlx.page/live/<org>/<repo>/main/<da-path>/<page-name>" \
-H "Authorization: Bearer $TOKEN"
Expect 200 OK. On success, report the live URL:
Live: https://main--<repo>--<org>.aem.live/<da-path>/<page-name>
da-auth-helper login (choose the Skyline profile).After a successful upload, ask the user if they want to keep or delete the local folders:
Upload complete. Delete /tmp/da-upload/ and /tmp/figma-media/ ? (y/n)
If the upload failed or the user wants to keep the folders, leave them in place.
Output:
https://www.adobe.com/ URLs with real destinations./tmp/da-upload/ (HTML) and
/tmp/figma-media/ (images), if not deleted.Source: adobecom/milo — distributed by TomeVault.