Inspiration

Every design-system team syncs Figma and code, and every tool does it by picking a winner: "Figma first" or "code first". The other side's work gets overwritten without anyone deciding. And even when the library is in sync, screens drift: someone detaches an instance, sets a colour by hand, resizes a button. We wanted an agent that keeps the system alive in every place it lives, knows which changes it can fix alone, and leaves the rest to a person.

What it does

Seamline checks GitHub's real Primer design system across Figma, code, Storybook and docs: over 1,500 values for Button, plus options, tokens, stories and status for all 74 React components. When something goes out of sync, NVIDIA Nemotron models on Nebius Token Factory decide what to do:

  • Nano pairs renamed tokens.
  • Ultra reads commits and tickets to decide which side is right, and applies only at ≥ 85% confidence.
  • Super researches new options with Tavily (other design systems, WCAG) before proposing them.
  • When both sides changed the same thing, Ultra summarises both and leaves the call to the design system lead. Its lean, if any, is shown as a hint next to a side-swap test, never pre-selected.

It opens a real GitHub pull request whose ds-sync check stays red until the lead answers in the console. "Send answers" pushes the decisions and the check turns green. The lead can also override a decision with a written reason: the check passes for 7 days and the reason is posted on the PR. Every change is logged and can be undone; three rejections of one kind pause auto-apply for it.

It also checks where components are used: six GitHub screens built from Primer instances in Figma. Rules catch detached instances, colours set by hand, contrast in all 9 Primer colour modes, off-scale spacing, deprecated or missing components, and tokens code doesn't ship. Meaning problems (a "Cancel" primary button, a Delete button with an "opens elsewhere" icon) are proposed by Nemotron Super and confirmed by Nemotron Ultra.

Everything that doesn't block the PR becomes a GitHub issue with an owner: screen problems (one issue per kind), components missing in Figma, Storybook or docs, and fixes Ultra suggests.

How we built it

  • TypeScript agent and checking engine on the real @primer/primitives and @primer/react packages, Primer's own Storybook stories at the same version, and the Primer Web Figma file.
  • Nebius Token Factory for every model call; NVIDIA Nemotron 3 Nano, Super and Ultra routed by task, so the big model is only used where judgment is needed.
  • Token Factory Sandboxes for the benchmark: one checkpoint, four parallel forks, one sync strategy each. Only the agent kept all five changes.
  • A daily GitHub Actions run checks, repairs and opens the PR; a small server on Vercel turns "Send answers" and "Create issue" into GitHub Actions runs. A Nebius Serverless Endpoints deploy workflow is included.
  • Every number in the console is computed from the run's data, and unit tests check that the data agrees with itself on every PR.

How we know it works

  • End-to-end: agent run → PR opens with ds-sync red → answers sent from the live demo → decisions commit lands → ds-sync green, no manual step on GitHub.
  • Planted breaks: 12/12 found across 5 screens.
  • Blind test: a screen built after the rules were frozen, with 6 new breaks and 6 correct decoys: 6/6 found, 0 false alarms.
  • Mutation test: 343 random single breaks across 9 kinds: 343/343 caught, 0 knock-on false alarms.
  • Side-bias test: the same Figma-vs-code conflict asked 5 times, 5 more with the sides swapped, 5 with no argument. Ultra picked neither side in all 15: no tilt towards designers or engineers.

Challenges we ran into

  • Telling real drift from noise: component-local CSS variables, fallback chains, alpha rounding and default options all looked like drift until we read the TypeScript API too.
  • Nano invented a commit when asked to judge, so judgment moved to Ultra.
  • Super didn't answer the same way twice. Temperature 0, row-level context and Ultra as a second reviewer made it stable.
  • Ultra's lean on a conflict wasn't stable across runs, so the console shows it as a hint with the side-bias result instead of a "suggested" badge.
  • GitHub was holding every check on bot-opened PRs as "action required". The workflow now approves and starts the check itself.

Accomplishments that we're proud of

Real findings in Primer itself: a misspelled variant in InlineMessage docs (unvailable), status mismatches between docs and Figma (Pagehead, NavList, DataTable, TabNav), 38 colour tokens in code with no Figma variable, 7 visual components with no Figma set, options the docs list but no story shows, and fgColor/accent, fgColor/link and fgColor/danger just under WCAG AA on bgColor/default in dark dimmed mode.

What we learned

Confidence thresholds plus an undo log make teams comfortable letting an agent touch their system. Routing by model size matters as much as the prompt, and a second model as verifier is cheaper than a better prompt. A model's recommendation needs its own stability test before it's shown to the person deciding.

Limitations

  • Button gets the deep checks; other components get lighter ones.
  • Storybook stories are read as source, not rendered. Screens are read from a Figma export in the repo, not live.
  • Model confidence is the model's own estimate, not calibrated.
  • An override lets the whole ds-sync check pass for 7 days, not just the overridden value.
  • Nebius Serverless is ready but not live (our credits cover Token Factory only), so the demo runs on Vercel.

What's next for Seamline

Agent repairs beyond Button, Figma write-back through the plugin API, live screen scanning as designers work, rendering stories to compare them visually with Figma, overrides per value, and per-team trust settings.

Built With

  • figma
  • github-actions
  • nebius-token-factory
  • node.js
  • nvidia-nemotron
  • primer
  • storybook
  • tavily
  • typescript
  • vercel
Share this project:

Updates

Submission history