xd-extractSAFE
Extract SVG vector art from Adobe XD share links and .xd files: inventory, export and validate. CLI plus agent skills.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://github.com/jeanpfs/xd-extract/actions/workflows/ci.yml) [](https://www.npmjs.com/package/xd-extract) [](https://github.com/jeanpfs/xd-extract/blob/main/LICENSE)
Extract SVG vector art from Adobe XD designs, from a public share link (xd.adobe.com/view/...) or a local .xd file. List the nodes, pick one, export it, and check the result.
XD share links draw into a `, so right-click and download give you nothing usable, and a screenshot is raster. The vector data travels as a scene-graph JSON (AGC) that the viewer only paints. xd-extract` reads that JSON directly and converts the node tree to SVG.
Status: 0.2.1, early
- Verified:
.xdfiles (one public sample), and a real share link that carries vector data (an XD 2.33 design with 6 artboards and 120 top-level nodes): the page, the manifest and every artboard were fetched on the first try, all 117 nodes with geometry converted, and the 26 exports that use masks (clipPath) validate. Only one such link has been tested. - Not verified on real data: the mask-drift correction (it never triggered; it has synthetic tests only),
/spec/links, password-protected links, and AGC versions other than1.5.0. The only public link we could find (an Adobe sample) is raster-only. If a link fails,xd inventory --record dircaptures the exchange (see Privacy) and an issue with the error code helps a lot. - SVG only. Background blur and angular gradients are not converted; text is emitted as live `` and needs its font on the viewer's machine. Each is reported as a warning; nothing is dropped silently. See What is converted.
- Developed and tested on macOS; CI runs on Linux. Windows is untested.
Quick start
Needs Node.js 22
6d8958c9bc05OBSERVED · 2026-10-14Install
Commands as the repository documents them. They are shown, not run.
npx skills add jeanpfs/xd-extract --list
npx skills add jeanpfs/xd-extract --skill xd-extract-svg -g
Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: xd-extract-svg
description: "Extract SVG vector art (icons, illustrations, logos, whole screens) from an Adobe XD share link (xd.adobe.com/view/...) or a .xd file, then validate it. Use when the user sends an XD link or file and wants SVG, says the download is disabled or the page is a canvas, or a screenshot is too low quality. Handles inventory, node selection by name or colour, frame (viewBox) selection and validation. Not for Figma or other formats."
---
# XD to SVG
Pull **vector** art out of an Adobe XD design. The art is never in the viewer's canvas: it arrives as a scene-graph JSON (AGC) that the viewer only draws. The `xd` CLI downloads that JSON (or reads it from a `.xd` file), converts the node tree to SVG and validates the result.
Output is **SVG only**. Angular gradients, background blur and inner shadows are not converted yet (object blur is); image fills are embedded in the SVG as data URIs (large ones may be refused: `--max-embed-bytes`); text is emitted as live `<text>` and needs its font; the tool reports each one as a warning instead of dropping it silently.
## Run the CLI
```bash
npx -y xd-extract <command> # or `xd <command>` when installed globally
```
Needs Node >= 22. Commands: `inventory`, `extract`, `validate`, `redact`. `xd --help` lists every flag.
## Inputs to ask for
Ask for both in **one round**:
1. **The source**: a share link (`https://xd.adobe.com/view/...`) or a path to a `.xd` file.
2. **What to extract** and **how to name each output file**. Accept loose descriptions ("the orange illustration", "the cart icon"); resolve them to node names during inventory and confirm the mapping in the report.
## Procedure
1. **Inventory.** `xd inventory <source> --json` lists every top-level node per artboard with its bbox, dominant fill colour, shape count and warning codes. Never print the whole AGC into the context; the inventory is the projection.
- Loose description by colour: `xd inventory <source> --find "#ff9c29"` ranks nodes by dominant fill.
- Several candidates or an ambiguous request: `xd inventory <source> --preview /tmp/xd-preview.html`, open it for the user (`open /tmp/xd-preview.html` on macOS) and let them pick. Cheaper than guessing.
2. **Extract.** One node: `xd extract <source> --node "<name>" -o out/<file>.svg`. Several: write a `map.json` (`[{"file":"cart.svg","node":"cart"}]`) and run `xd extract <source> --map map.json -d out`. If the same node name exists on several artboards, add `--artboard "<name>"`.
3. **Validate.** `xd validate out/*.svg` (add `--expect-same-frame` when the set should share one frame). Exit code 1 means at least one `error`. Read `references/defects.md` for what each finding means.
4. **Look at the pixels.** Validation does not prove correctness. Open the preview in the user's own browser and check every export; see `references/defects.md` for what a defect looks like. Never skip this.
5. **Report**, for every file: source node, artboard, output path, `viewBox`, frame rule (`plate` or `content`), every mask snap, and every warning. Name the exact source so the extraction can be re-run after a design update.
## When it fails
| Error | Meaning | Do |
|---|---|---|
| `NoVectorPayload` | The link is a raster-only prototype: no AGC exists to convert. | Tell the user and stop. Do **not** screenshot, trace or redraw. |
| `PrivateLink` | The page exposes no manifest (private, password, or an unseen layout). | Retry once with `--browser` (needs `agent-browser`). If it still fails, ask for a public link or the `.xd` file. |
| `TokenExpired` | The manifest or an AGC request was refused. | Ask for a fresh link; retry with `--browser`. |
| `LinkNotFound` | The link answers 404/410. | Ask for the right link. |
| `TargetNotFound` / `AmbiguousTarget` | The node name does not match, or matches several nodes. | The error lists the available names or candidates: pick one, add `--artboard`. |
| `NoPaintedGeometry` | The node has no painted shapes (text only, or everything hidden). | Pick another node. |
## Warnings
`unsupported-fill:gradient|pattern`, `unsupported-stroke:*`, `unsupported-shape:*`, `unsupported-node:*` (including a symbol instance whose master was not found) mean art is **missing** from the SVG and validation fails on them. Report it to the user; do not hand-draw the missing part. `skipped-text`, `unsupported-style:filters` (shadows, blur), `unsupported-style:clipPath` and `stroke-align-ignored:*` are visible differences from the design; list them in the report.
## References
- `references/rules.md` : why each conversion rule exists, and how the frame (`viewBox`) is chosen.
- `references/defects.md` : defect to cause table, mapped to validator codes.
- `references/canvas-viewers.md` : the generic method for design viewers that render into a `<canvas>`, for formats the CLI does not cover.
## Hard rules
- **Never** deliver a canvas screenshot, a traced bitmap or a hand-drawn approximation as if it were the extracted vector. If the vector payload is unreachable, say so and stop.
- **Never** skip the visual check. XML-valid and correct are unrelated properties.
- Write exports to a dedicated directory (for example `xd-export/`). Do not overwrite project assets unless asked; replacing a raster with an SVG usually also needs code changes (for example React Native `<Image source={require(...)}>` to an SVG component).
- Do not commit exports or preview pages without being asked.
- `--record` and `redact` operate on the user's design. Recorded files contain the full design JSON; never commit them. `redact` keeps geometry, so the artwork itself must be cleared for publication.Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (1 observation(s))
- Network
- declared (1 observation(s))
- Shell
- declared (1 observation(s))
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (5)
const ROOT = join(import.meta.dirname, '../../../fixtures/public');
tsconfig: '../../tsconfig.json',
import { loadShareLink } from '../../src';const dir = join(import.meta.dirname, '../../../fixtures/recorded/sample-prototype');
head = Uint8Array.from(atob(b64.slice(0, 24)), (c) => c.charCodeAt(0));
Gates applied: no_behavioural_pass.
6d8958c9bc05full audit observations/trust-audit/skill/jeanpfs__xd-extract.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-14 | 6d8958c9bc05 | SAFE | B | 89 | first audit |
Questions
What does the xd-extract skill do?
Extract SVG vector art from Adobe XD share links and .xd files: inventory, export and validate. CLI plus agent skills.
Is xd-extract safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can xd-extract access on my machine?
The audit observed that it reaches the network, runs shell commands and reads or writes files. Each of those is consistent with what it says it does. Secrets in the source: none found.
What do I need installed to use xd-extract?
Its own instructions reference agent-browser. Dependencies are pinned to exact versions.
Which assistants does xd-extract work with?
Its documentation mentions claude-code. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (6d8958c9bc05), read on 2026-10-14. The repository is watched, and a new audit runs when it changes — this is the first audit.