| name | sync-design-bundle |
| description | TRIGGER when user asks to sync, refresh, re-export, pull, or update the Fini design bundle from a claude.ai/design URL (`https://api.anthropic.com/v1/design/h/<hash>`). Workflow: agent uses WebFetch to download the gated URL, then a bash script swaps the gzipped tar into the repo root, replacing only `chats/`, `project/`, `README.md` and preserving everything else. |
sync-design-bundle
Refresh the design handoff bundle. Authoritative source = a Claude Design export URL that returns a gzipped tar.
The URL is gated by the user's claude.ai session — plain curl hits 404. The reliable path is Claude Code's WebFetch tool, which authenticates implicitly. This skill assumes it is invoked by an agent with WebFetch available.
URL ephemerality. Claude Design export URLs are short-lived (observed: a few hours). They expire even within a single Claude Code session. When WebFetch returns 404 / non-binary, the URL is dead — ask the user to open claude.ai/design, re-export the project, and paste the fresh URL. Persist it to .design-bundle-url after a successful sync so future no-arg runs are clean until the URL ages out.
Inputs
- A Claude Design export URL of the form
https://api.anthropic.com/v1/design/h/<hash>.
- If the user supplies a URL in the request, use that.
- Else read it from
<repo>/.design-bundle-url.
- When the user supplies a new URL, after a successful sync overwrite
<repo>/.design-bundle-url with it (printf '%s\n' "$url" > .design-bundle-url).
Workflow (agent steps)
-
Resolve URL — from user message or .design-bundle-url. Validate it matches https://api.anthropic.com/v1/design/h/.
-
WebFetch the URL. Prompt can be minimal (e.g., "download bundle"); the response body is binary, so WebFetch will report:
Binary content (application/gzip, NMB) also saved to /home/<user>/.claude/projects/<id>/.../tool-results/webfetch-<n>-<rand>.bin
Capture that absolute path.
-
Run the sync script with the captured path:
bash .agents/skills/sync-design-bundle/scripts/sync.sh <saved-path>
The script:
- copies the file to
/var/tmp/fini-design-bundle.tgz
- validates it's a gzipped tar with exactly one top-level dir
- validates the top-level dir contains
chats/, project/, README.md and nothing else
- extracts to
/var/tmp/fini-design-staging/
- removes
chats/, project/, README.md at repo root and moves the new ones in
- prints
git status --short
-
Persist URL if the user supplied a new one this run:
printf '%s\n' "<url>" > .design-bundle-url
-
Review and commit. Expected git status shape:
M README.md
M chats/...
M project/...
[?? new files in those dirs]
[ M .design-bundle-url (only if URL changed)]
Anything outside chats/, project/, README.md, .design-bundle-url is a bug — stop and investigate before committing.
Commit message: chore: refresh Fini Design System bundle.
What gets touched
Replaced at repo root:
chats/
project/
README.md
Preserved:
.git/, .agents/, .claude/, AGENTS.md, CLAUDE.md, .design-bundle-url, .gitignore, anything else not in the replaced list.
Failure modes
| Stage | Failure | Recovery |
|---|
| Resolve URL | No URL in user message and .design-bundle-url missing/empty | Ask the user for the URL. |
| WebFetch | 404 / text body / no "saved to …" line | URL has expired (typical — they live a few hours). Ask user to re-export on claude.ai/design and paste the new URL. Update .design-bundle-url after a successful sync. |
| sync.sh exit 3 | Input not a valid gzipped tar | The file at <path> isn't what we expected (HTML error page, partial download). Inspect /var/tmp/fini-design-bundle.tgz. |
| sync.sh exit 4–7 | Tarball shape unexpected (multi-root, missing chats/project/README.md, or extra siblings) | Bundle format may have changed. Update this skill before proceeding. |
| Mid-swap interrupt | Repo paths half-replaced | git checkout -- chats project README.md to roll back, then re-run. |
Notes
- Staging stays at
/var/tmp/fini-design-staging/ after a run — safe to inspect.
- Cached tarball at
/var/tmp/fini-design-bundle.tgz — overwritten each run.
- The bundle's own
README.md (the "CODING AGENTS: READ THIS FIRST" doc) is replaced on every sync; project-level agent guidance lives in AGENTS.md (and CLAUDE.md symlink), which are preserved.
- This skill does not run
curl against the URL. The auth path is WebFetch; if a future API-key path opens up, add it here.