neuron-explorer
Steering-first neuron explorer for Qwen3.5-4B: push every MLP neuron, keep every rollout, browse the results
翻译准备中
Sync Storybook.js to Figma.
翻译准备中
开发工具TypeScript · JavaScriptGitHub @brendanciccone自行安装运营者未确认
试用过了吗? 点一下就好,无需登录。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
安装型项目无需部署域名也可验证。个人仓库可通过 GitHub 登录验证,组织仓库可使用上方的仓库验证文件。
正在加载完整 README。 以下为已保存的摘录。
Sync your design system from code to Figma, and diff Figma back against code, using Storybook MCP and Figma MCP.
storysync reads design tokens from your codebase (Tailwind config, CSS custom properties, or theme files) and components from Storybook MCP. Your AI client then uses Figma MCP to create matching Figma variables and component sets.查看完整 README ↗Sync your design system from code to Figma, and diff Figma back against code, using Storybook MCP and Figma MCP.
Start here: What it does · Install · Your first push · What a push costs · Check the result · Find drift · What Figma can't do
Reference: docs/reference.md has every command and flag, how each step works, tokens, the GitHub Action and troubleshooting.
Storysync reads design tokens from your code (a Tailwind config, CSS custom properties or theme files) and components from Storybook MCP. Your AI client then uses Figma MCP to create matching Figma variables and component sets.
Component styling is measured, not guessed:
storysync snap renders every variant of every component in a headless browser and records the computed styles of each element that draws: fills, spacing, radii, type, icons and pictures.storysync figma code turns those measurements into the Figma calls your AI client sends, unchanged.storysync verify reads Figma back and scores it against the measurements, element by element.There are three workflows: push (code to Figma), verify (score what landed against what rendered) and diff (find drift in either direction). Storysync never writes your code. See Non-goals.
| Use it from | What it does |
|---|---|
| Claude Code, Cursor or Codex | A skill file runs the CLI commands, sends the Figma calls through use_figma, and scores the result with verify. It can also audit Figma against code. |
| The CLI | Extract tokens, map components, measure rendered styles, write a push's Figma calls, score a push, or diff Figma against code. |
| GitHub Action | Catch token and component drift in CI. |
Why a skill file? Writing to Figma needs Figma's use_figma tool, which works only inside supported MCP clients such as Claude Code, Cursor and Codex. So the CLI does the extracting and the measuring and writes every Figma call, for tokens and components alike, and the skill tells your AI client to send those calls and run the commands around them. Storysync needs no Anthropic API key and makes no LLM calls of its own.
For components:
@storybook/react-vite, @storybook/nextjs-vite or @storybook/sveltekit.@storybook/addon-mcp, which serves MCP at /mcp. storysync init sets it up.storybook dev), not a static build.snap.For writing to Figma:
For tokens: Node.js 18 or later, and nothing else. Token extraction reads only local files, so it needs no Storybook, MCP connection or sign-in.
npm install -g storysync # or: pnpm add -g storysync
cd your-project
npx storysync init # set up @storybook/addon-mcp if needed
npx storysync setup --client claude # or: --client cursor, --client codex
setup writes the skill file, plus slash commands for Claude Code, and prints the MCP setup commands you still need to run.
To try Storysync without a project of your own, use examples/storybook-vite. It's a small Storybook with one component that measures cleanly and one whose story is broken on purpose, so you can see the warning.
Connect your client to both MCP servers, start Storybook, and ask for a push.
claude mcp add --transport http storybook http://localhost:6006/mcp
claude plugin install figma@claude-plugins-official
Start Storybook, open Claude Code, and run /storysync-push <figma-file-key>. The file key is the part of a Figma URL between /design/ and the next /.
storysync setup --client cursor writes the rule to .cursor/rules/storysync.mdc. Add Storybook MCP to .cursor/mcp.json:
{
"mcpServers": {
"storybook": { "url": "http://localhost:6006/mcp" }
}
}
In Cursor's Agent chat, type /add-plugin figma and sign in to Figma. Then start Storybook and ask the agent to push.
Cursor's terminal sandbox blocks localhost, so the agent asks to run storysync list, map, inspect and snap outside it, and figma upload, which posts pictures to Figma. Approve them: they need to reach Storybook or Figma.
storysync setup --client codex writes the skill to .agents/skills/storysync/SKILL.md. Then add the MCP servers:
codex mcp add storybook --url http://localhost:6006/mcp
codex mcp add figma --url https://mcp.figma.com/mcp # signs you in to Figma
With Storybook running, ask Codex to push. In the CLI, you can type $storysync to name the skill. See Codex details for the sandbox and timeouts.
These work in every client:
| Goal | Say |
|---|---|
| Code to Figma | "Push my Storybook to Figma (file key <key>)" |
| Audit drift | "Diff Figma against code (file key <key>)" or "Check if Figma is in sync" |
| Score the last push | "Verify the Figma file against the measured styles" |
The skill walks your agent through these steps. It stops and asks you whenever a choice is yours.
storysync tokens --json reads your tokens, and storysync figma tokens writes a call per collection that the agent sends to create or update its Figma variables. A dark theme becomes a Dark mode beside Light.storysync list counts them. With more than about 20, the agent asks which to push.storysync snap --variants all renders every combination of every component's variant props. It runs in the background, since it can take minutes.storysync figma code writes every Figma call as a file and prints an estimate of what the push will cost. The agent shows you the estimate and waits for your go-ahead. Where a translucent color such as bg-destructive/10 binds to a variable, the first call adds one that carries its opacity, destructive 10%, so it stays translucent when a designer switches a frame to Dark.use_figma unchanged and saves each response unchanged.storysync verify --plan reads the responses and scores Figma against the measurement. The agent reports the score, what differs, and what it couldn't score.The Figma file mirrors Storybook's sidebar: a page per category, and a component set per component, named by the last segment of its title.
A push isn't lightweight. Your AI client sends every Figma call through its own context: each build call carries up to 45,000 characters of code, and each read call returns up to 20kb. That adds up in tokens.
Rule of thumb: plan on roughly 100k tokens per component, plus about 100k per push for setup and verification. Simple components use less. Components with big variant grids use 2 to 3 times more.
| Components | Plan on about |
|---|---|
| 10 | 1.1M tokens |
| 30 | 3.1M tokens |
| 60 | 6.1M tokens, split across sessions |
These numbers are calibrated from live pushes. One of them built 5 components with 100 variants and 872 elements in 22 calls, for about 570k agent tokens.
The estimate for your push. storysync figma code prints an estimate for the calls it just wrote: how many calls, the characters the agent must send and read back, and a token range. The low end puts each character the calls carry at about 0.8 tokens, plus 100k for the push and 10k per component; the high end allows for a repair round and questions. --json puts it in estimate.
To spend less, push fewer components at a time with --components, in separate sessions.
Writing to the canvas is free during Figma's beta. Figma's guide to its MCP server says it will become a usage-based paid feature.
The push ends with storysync verify, which scores what Figma holds against what snap measured:
Fidelity: 99.8% of elements (29 of 30 verified), 99.7% of properties (389/390)
worst: Forms/Button 99.8% of elements
missing 0 · drifted 1 · extra 0 · designer layers 0 · not measured 0
coverage 92.9%: not scored: line-height: normal, which each font's metrics set on Forms/Button › #text; ...
~ Forms/Button variant=primary, size=sm, disabled=false › #text: color measured #ffffff, Figma #ff00ff (node 1:2)
14 verified, 1 drifted, 0 missing from Figma, across 15 variants
The comparison is numeric, not visual, so it's deterministic and free. See How verify scores for the details.
Test the score once on your own file. A score is only as good as the readback behind it:
verify --plan. It should report exactly that element, by its key and node id, and nothing else..storysync/figma/results/ and run verify --plan again. That entry, and only that one, should fail its checksum.Don't test it by moving a layer that sits in auto layout. To move, it has to leave the flow, so the layers after it move up and the frame around it shrinks, and verify reports those too, as Figma now has them. Storysync's own tests run both checks on the example project, and each edit on five shadcn/ui components, then send the build calls again and check that everything verifies.
Ask your agent to diff Figma against code, or run /storysync-diff <figma-file-key> in Claude Code. The audit reads Figma's variables and component sets and compares them with storysync tokens and storysync map:
+ missing from Figma in code, not in Figma
- missing from code in Figma, not in code
~ value mismatch both exist, values differ
It compares token values and each component's variant properties. It needs use_figma to return what its code returns, which supported clients do. Asked whether the sets still look like the code, it can also score them as verify does, reading Figma and changing nothing.
The CLI's own storysync diff does the same comparison, given a Figma MCP endpoint it can reach without signing in. To catch drift in CI, use the GitHub Action.
snap measures what your stories render, so a few habits help:
?args= URL. A story that hardcodes props, uses a custom render that ignores its args, or has a decorator that drops them renders its default for every variant. Plain CSF3 args-driven stories are the reliable shape.data-slot (switch for Switch), as shadcn/ui puts on every component's root. Any project can point snap at a root the same way.--stories.open or defaultOpen prop the story passes through is the surest way.snap warns about each of these when it sees them. See How snap measures.
These are true limits of Figma's platform. Each comes with what Storysync does about it.
loadFontAsync), and the Plugin API can't install one. A font your code loads that Figma lacks is drawn in a stand-in at the measured weight, and the build names it. Install the font in Figma yourself. For system fonts, snap measures in the stand-in Figma will use, so widths match.clipsContent: boolean). An element that clips one axis is built clipping both, and figma code names it.VariableBindableNodeField lists none, a paint's only bindable field is its color, and binding one fails with Unknown field: 'blendMode'. No one blend draws both themes of Avatar's ring either: Light's mix-blend-darken never lightens, and Dark's dark:after:mix-blend-lighten ring only lightens. So the ring is built with the light theme's blend and shows in Light only, and figma code names each layer whose blend changes in Dark.use_figma signs nothing. The readback checksum is a 32-bit FNV-1a over each entry, computed by the readback template that ships with Storysync. It catches a response edited, cut down or copied on the way, and a shortcut such as writing the readback from snap's values. It can't catch forgery, a readback reused after a fix round, or a template that echoes what it sent instead of reading the nodes. The score test covers that: change an element in Figma by hand, read it back, and verify should report exactly that element.The reference covers the rest:
MIT
verifyuse_figma takes at most 50,000 characters of code a call and returns at most 20kb (write to canvas), and it can't create images. figma code packs calls under these limits: the first build and read store their template in the file for the rest, a variant too big for one call is sent in parts, reads continue with figma next, and pictures go through upload_assets.