Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
git clone --depth 1 https://github.com/brendanciccone/storysyncWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/commands/brendanciccone/storysync/storysync-diff)<a href="https://agentmods.dev/commands/brendanciccone/storysync/storysync-diff"><img src="https://agentmods.dev/badge/commands/brendanciccone/storysync/storysync-diff/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/commands/brendanciccone/storysync/storysync-diff"><img src="https://agentmods.dev/badge/commands/brendanciccone/storysync/storysync-diff.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00012 | $0.02796 |
| Opus 5.5 | $0.00005 | $0.01118 |
| Sonnet 5.5 | $0.00002 | $0.00559 |
| Haiku 4.5 | $0.00001 | $0.00280 |
Grade A, and why
storysync-diff scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 23d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 30 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Compare the current Figma file against this codebase's design tokens and Storybook components, then report drift in either direction. Use the storysync skill at .claude/skills/storysync/SKILL.md (Audit section).
Figma file key: $ARGUMENTS
If the user did not provide a file key (or $ARGUMENTS is empty), ask for it. The file key is the part of a Figma URL between /design/ and the next /.
Workflow. The step numbers here are this command's own: steps 1 to 6 are the skill's Audit steps 1 to 6, steps 7 and 8 its step 7, and step 9 its step 8.
- Read Figma variables: call
use_figmato enumerate every variable collection and its resolved values (usefigma.variables.getLocalVariableCollectionsAsync()and convert COLOR values to hex,#rrggbbwith the alpha as two more digits when it comes to less thanff). It reads each variable in its collection's first mode and, in a collection of several modes, in each, asmodesby mode name, for step 5 to compare theDarkone with the code's dark theme.use_figmareturns at most 20kb per call, which a full palette passes, so read them a slice per call with the skill's template, from thenexteach call returns until it isnull. - Read Figma components: call
use_figmato enumerate every component set and its variant properties, and every component outside a set (the push makes a component with no variant properties a plain component), a page at a time:use_figmaloads pages as it switches to them and does not supportfigma.loadAllPagesAsync(), so a search fromfigma.rootsees only the pages already loaded and misses the sets on the rest. List the pages (figma.root.children), then make one call per page with the skill's template: it switches to the page withfigma.setCurrentPageAsync, usespage.findAllWithCriteria({ types: ['COMPONENT_SET', 'COMPONENT'] })without the sets' variants, and returns each one'snodeId, type, thestorybookIdthe push stored on it (getSharedPluginData('storysync', 'id')) andcomponentPropertyDefinitions, as many per call as fit under 20kb, from thenexteach call returns as in step 1. Figma throwsComponent set has existing errorsreading a set it flags as errored: the template returns that set with itserrorand reads on. - Run
npx storysync tokens --json --project .for code-side tokens. If its warnings say storysync can't read or find part of the Tailwind config, or doesn't follow it, or read no theme from it, code is missing the tokens that part declares: in step 7, report a Figma variable that code lacks as possibly coming from what the warning names, not as orphaned, and name the warning. - Run
npx storysync map --storybook http://localhost:6006 --jsonfor code-side components. map leaves out what the push left out, reading each component'sexcludedPropsfrom.storysync/snaps/styles.json, which keeps the record of every component a push measured, and takes the props the stories' argTypes and args add from it too; pass--snap <dir>if the push's snap is elsewhere. Without that file, pass the--exclude-propsthe push used, if any, from the push's summary, which names them; otherwise every prop it left out is reported missing from Figma. If neither has them, and props come back missing from Figma on components the push made (those with astorybookId), ask the user whether the push left those out before reporting them. If the user asked about some components only, first runnpx storysync list --storybook http://localhost:6006 --jsonfor every component'sid,name,titleandcategory, to pair with in step 6, then pass map with--componentsonly the scope's names that list has (byid,title,nameor the last segment oftitle, ignoring case) rather than map every component, which can take many minutes: map refuses a name Storybook doesn't have, and a name only Figma has is for step 6. If list has none of them, skip map. - Compare tokens by name within each category. storysync's own alpha and per-mode variables (
destructive 10%,destructive 10% dark 20%,background dark input 30%,input 0% dark 30%,slate-50 dark slate-900,[#3f3f3f] dark [#e8e8e8]) are not missing from code while each color in the name is a code token (the one afterdarkwritten as a class names it,muted-foregroundformuted/foreground), a Tailwind palette color or an arbitrary[#rrggbb]: leave them out of the report; one whose token is gone is-. Normalize before comparing: compare a color by its token'shexand a length by itspx(rem andcalc()worked out) where the token has one; otherwise lowercase hex, convert rem→px, strip units. A translucent color is#rrggbbaaon both sides: compare all eight digits. Round numbers to thousandths on both sides. Match Figma collection names to code categories (Colors→colors, Border Radius→radius, etc.). Compare each collection's first mode with the token's light value and, where thetokensoutput'smodesincludesDark, each variable'sDarkmode with the token'sdarkhexorpx, or its light ones where it has nodark; a token with adarkwhose collection has noDarkmode is missing from Figma in Dark. Note what can't be compared, for step 8 to name: every mode of a Figma collection but its first and theDarkone, and theDarkone too where thetokensoutput'smodeshas noDark; the tokens atokenswarning says it didn't read (Unresolved:,Skipped dynamic value:,Not read from @theme,Uncategorized:); and the categoriestokenshas no collection for in a project on Tailwind, whose components use Tailwind's default spacing, type or shadow scale, whichtokensdoesn't extract. - Compare components by Storybook ID first: a Figma component whose
storybookIdis a code component'sidis that component's, whatever its name or page (two with it, as a copy of a set has, are told apart by page as below), and one whosestorybookIdno code component has is Figma only, never paired with another component by name. Compare the code components no ID paired with the sets that have nostorybookIdby set name (case-insensitive): the last segment of a component'stitle, or itsnamewithout one, or itsnamewhere no set has that and it is no other component's set name. A name only one code component and one set have is a pair. If two code components share a name, or two Figma component sets do (on different pages: an archived copy, say, or each category's ownButton), counting those an ID paired, pair a component with the set of its name on its category's page (Componentswithout one, comparing page names ignoring case, spaces,/,-and_) where each is the only one of the name on that page on its side; of the copies left, code's alone are code only and Figma's alone Figma only. Copies left on both sides, even one of each, can't be told apart (a set on another page may be the component's, moved, or an archived copy beside a component not pushed yet): report the name as ambiguous, and only as ambiguous: compare none of the copies left, and don't also count them as matched, mismatched or missing. A component outside any set with nostorybookIdmay be a designer's own, such as an icon: it pairs only with a code component the sets left code only, of its set name and on its category's page, each the only one there, and never makes a name ambiguous. One left unpaired is not one the push made, since the push stores astorybookIdon each component it makes: don't list it as Figma only, but count it as not compared, unless the scope names it. A set with anerrorpairs as any set, but is reported as errored in Figma (can't read its properties), by name, page andnodeId, with nothing in it compared; don't delete it unless the user asks. When the audit is scoped, pair with every componentlistgave, but compare and report only those in scope, and a Figma component paired with none only if the scope names it; a name in the scope that neitherlistnor Figma has is a typo: say so. For each pair: missing props, extra props, missing/extra values per prop. - Report drift grouped by category/component:
+missing from Figma (in code, not in Figma)-missing from code (in Figma, not in code)~value mismatch (both exist, values differ)?ambiguous (a name two code components or two Figma component sets share, none of its copies compared)!errored in Figma (a set whose properties Figma won't give, compared with nothing)
- End with a summary: N tokens matched / mismatched / missing. N components matched / mismatched / code-only / Figma-only / ambiguous / errored in Figma, and N components outside any set not from the push, not compared. Beside the token counts, say what they cover and what they don't, so
39 matchedisn't read as every token in both themes:39 matched (colors and radius, in Light and Dark; not compared: the High contrast mode of Colors, font/sans and font/mono, which tokens couldn't resolve, and Tailwind's default spacing, type and shadow scales, which have no tokens). Confirm "Figma and code are in sync." only if everything matches and no name is ambiguous or set errored; components outside any set not from the push don't count against it. An ambiguous name was compared on none of its copies, and an errored set on nothing, so either can hide drift: while any is, name them instead, and never say the two are in sync. Say with it what the audit compares: tokens, in the modes it noted, and each component's variant properties, not the styles the push'sverifyscores. - When the user asks whether the sets look like the code, not only whether their names and values agree, score them as the push's
verifydoes, reading Figma and changing nothing, with the skill's Audit step 8: snap the components in scope with--out .storysync/audit/snaps(in the background, with--variants all, the push's--exclude-propsand--keep-props, and the push's--stories,<id>=<storyId>for each component in scope from thestoryIdthe push's.storysync/snaps/styles.jsonrecords, ending it with!where the component recordsstoryOnly: true, as innpx storysync snap --storybook http://localhost:6006 --variants all --out .storysync/audit/snaps --json), runnpx storysync figma code --snap .storysync/audit/snaps/styles.json --out .storysync/audit/figma, send only the plan'sreadcalls, never itsbuild,imagesorlabelcalls, saving each response unchanged and continuing each withnpx storysync figma next --plan .storysync/audit/figma/plan.json --seq <its seq>, then runnpx storysync verify --plan .storysync/audit/figma/plan.json. Add to the report each component's element fidelity and differences by key and node id, elements missing or no longer measured, designer layers, pictures not filled, sets an earlier storysync pushed root-only (their variants read asnot built by storysync, which a push deepens), sets no read found, and that the element-tree readback doesn't read variable bindings yet. Never fix what it finds in the audit.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 23d ago Changed · +2 lines 1b2039d7b978
- 1mo ago Changed · +1 lines 3f79a830994e
- 2mo ago First seen · 27 lines · 12 tokens per session scan A 072cbde49679
storysync-diff is a command published in the GitHub repository brendanciccone/storysync (75 stars, last pushed 8d ago), licensed MIT. It adds 12 tokens to every session and 2,796 once invoked, about $0.0000 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
storysync-diff compared with commands from other repositories
| Mod | Type | Stars | Last push | Licence | Scan | Tokens | Works with |
|---|---|---|---|---|---|---|---|
| storysync-diffbrendanciccone/storysync | Command | 75 | 8d ago | MIT | A | 12 | Claude Code |
| profilecathrynlavery/diagram-design | Command | 65k | 3d ago | MIT | A | 16 | Claude Code |
| erne-animateJubaKitiashvili/everything-react-native-expo | Command | 50 | 29d ago | MIT | A | 21 | Claude Code |
| ui-flow-reviewMRCalderon3D/everything-game-dev-code | Command | 104 | 28d ago | MIT | A | 15 | Claude Code |
| responsive-design-specialistimsaif/design-with-claude | Command | 11 | yesterday | MIT | A | 36 | Claude Code |
| design-auditw2ur/claude-code-setup | Command | 2 | 3d ago | MIT | A | 30 | Claude Code |
| ppt-image2-editable-rebuildwwe-dog/ppt-image2-editable-rebuild | Command | 204 | 5mo ago | Unlicense | A | 15 | Claude Code |