David Bowman

FigmagentNo. 026

This is a group of components generated by Figmagent from an existing codebase. All component instances are correctly linked to their Figma libraries and all available Figma variables are properly applied.
❯ I need you to compare our Figma file to the current state of the sidebar
  code. Audit it and give me a list of the differences.

  Searched for 2 patterns, read 2 files, called Figmagent 17 times, ran 14 shell
  commands

⏺ Audit done. Figma board 2285:361 ("Workflow sidebar — Next steps pattern
  (option B)", 7 states) vs vip-workflow/src/editor/.

  Structural — whole sidebar

  1. Card chrome vs flat sections. Figma wraps every region in a Card: fill
  wpds-color/background/surface/neutral-strong, 1px stroke/surface/neutral-weak,
  radius border/radius/lg (8px), Card.Content padding 24. Sidebar frame itself
  has 12px padding + 12px item spacing between cards.
  Code renders flat — .vip-workflow-sidebar > * { padding:
  var(--wpds-dimension-padding-lg) } (16px), no card, no border, no radius.
  index.js states this deliberately ("no card, no border of its own"). Every
  state below inherits this difference; not repeated per state.

  2. Card / Tools does not exist in code. Figma has a collapsible card (header
  "Tools" + chevron-up) between Workflow and Editorial Metadata. Inside: tools
  grouped by destination stage under arrow labels (→ Copy edit, → Published);
  each tool a 12px-padded tile with name + small secondary Run; the run one
  carries an inline result — check glyph + 82/100, a summary sentence, three
  severity-tinted issue rows (issue--error / --warning / --info), and …and 2
  more.
  Code puts required tools inside the rail, nested under each transition button
  (TransitionRail.renderCheck): indicator dot + secondary button labelled with
  the tool, then CheckIssues — Blocks:/Warns: prefixes, a rollup line ("Blocks
  this move." / "Warns before moving."), a + %d more collapsible, and Open full
  result → CheckResultsModal. No score, no card, no per-destination grouping, no
  Run label (button label is the tool name).
  Also: Figma's → Copy edit group is the current stage, which has no outgoing
  transition in that frame — that grouping has no equivalent in the code's
  per-transition model.

  3. Editorial Metadata card + heading. Figma: collapsible card, header
  "Editorial Metadata" + chevron. Code: MetadataPanel is a bare <Stack
  gap="xs">, no heading, no Jump to bottom (click) ↓ ck says so explicitly).

────────────────────────────────────────────────────────────────────────────────
❯ 
────────────────────────────────────────────────────────────────────────────────
  davidbowman@MacBookPro | vip-workflows | main?
  CTX 30% ███████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  ⏵⏵ auto mode on (shift+tab to cycle)
This is the output when the agent is prompted to inspect Figma and the corresponding code and compare the two.
⏺ Board synced. Version history is the undo if any call was wrong.

  What changed

  All seven states — card chrome gone. Removed fill / 1px stroke / 8px radius
  from every Card, renamed to vip-workflow-panel, moved the inset off the
  sidebar shell (12 → 0) and onto the panel (24 → 16), so content width is now
  248 as shipped. Panel gap lg (16), except No-workflow which keeps md (12) to
  match its branch.

  Workflow assigned — rebuilt as the flat stack the code renders: workflow row →
  assignment → rail → metadata → foot. The section wrapper is dissolved.
  Sequence name is now a SidebarRow (label + value trigger) instead of static
  text. Assignment moved above the rail, tinted surface-info-weak at radius md,
  with an avatar before the name and "(you)" in the success tone. Metadata is
  four SidebarRows inside vip-workflow-metadata-panel, ruled off above. Foot
  ruled off too. Show History → Show history.

  Tools card deleted; the checks it carried now sit where the rail actually
  renders them — nested under the Publish transition, past its border: indicator
  glyph outside a secondary check button, then the issue detail (roll-up,
  bullet lines with grade words, + 2 more, Open full result). Kept both
  treatments: one reported check, one never-run (neutral dash).

  Rail track redrawn. Adding the check rows moved the transitions, so the static
  arrowheads no longer pointed at anything. Re-aimed all four plus the wavy
  break at the new row centres, and restored the vector geometry — the earlier
  track widen had scaled them 19% off (SCALE constraints).

  No workflow — select-plus-Start form replaced by an empty workflow row.

  AI running / AI failed / Complete — same flatten, workflow row added, foot
  ruled off and re-labelled. Failed state: Re-run agent → Go back to Editorial
  review, and its routed exits now render withheld (grey stroke, muted label,
  leading pass/fail dots). Complete: heading is Workflow Completed with the
  stage name demoted to a muted line under it, End pill deleted, and the track
  emptied — a finished workflow draws no trunk.

  Board retitled Workflow sidebar — shipped states (was "Next steps pattern
  (option B)"), subtitle rewritten, and the three captions the rebuild
  invalidated updated.

  Deliberately not synced   Jump to bottom (click) ↓

────────────────────────────────────────────────────────────────────────────────
❯ 
────────────────────────────────────────────────────────────────────────────────
  davidbowman@MacBookPro | vip-workflows | main?
  CTX 30% ███████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  ⏵⏵ auto mode on (shift+tab to cycle)
This is the output when the agent is prompted to update Figma based on the code.
This is the result of the agent’s work after being prompted to bring the Figma file in line with the changes made in code. You can see there are some small errors. I’ve found almost all of these happen with custom components and actually point to improvements that can be made in the repo.
⏺ Done. Both boards live on the Brands page.

  Components board — Brand editor · components

  ┌─────────────────┬───────────────────────────────────────────────────────┐
  │    Component    │                         Notes                         │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Subtitle        │ Heading S, uppercase — core's                         │
  │                 │ .global-styles-ui-subtitle                            │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │                 │ the one nav-row shape. Props: Label, Icon?/Icon       │
  │ Row             │ (swap), Leading?/Leading (swap → ColorIndicator or    │
  │                 │ Swatch stack), Badge?, Chevron?                       │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Swatch stack    │ ZStack cluster, −8 offset                             │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Screen header   │ back + title + description. Props: Title,             │
  │                 │ Description, Description?, Back?                      │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Detail header   │ Screen header + ⋮ menu                                │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Group header    │ Subtitle + add/⋮ action                               │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Scale count     │ ScaleCount / FontSizesCount shape                     │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Brand name      │ full-width name button + Default badge                │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Style preview   │ PreviewStyles card                                    │
  │ tile            │                                                       │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Ramp step row   │ swatch + step + hex                                   │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Ramp swatch /   │                                                       │
  │ Ramp swatch     │ circular-option-picker + SearchControl                │
  │ picker          │                                                       │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Preset value    │ set, Mode = Token / Token search / Custom /           │
  │ control         │ Expression                                            │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Logo control    │ set, Has logo = False (dashed, accent) / True (solid) │
  ├─────────────────┼───────────────────────────────────────────────────────┤
  │ Rename dialog   │ modal chrome + InputControl + Cancel/Save             │
  └─────────────────┴────── Jump to bottom (click) ↓ ───────────────────────┘

────────────────────────────────────────────────────────────────────────────────
❯ 
────────────────────────────────────────────────────────────────────────────────
  davidbowman@MacBookPro | site-foundry | wpds-audit                       /rc
  CTX 43% ██████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  ⏵⏵ auto mode on (shift+tab to cycle)
Output when prompted to recreate components from code while correctly using published Figma libraries.
The agent is pretty good at creating component sets in Figma and using design systems correctly.

Figmagent is a custom MCP and harness for using AI agents inside of Figma for design tasks, not just for code extraction or vibe-y prototypes.

Figmagent was designed to make routine junior-level design work reliable and efficient. I made it as a tool for myself because I found agentic design tools extremely lacking: they were either big “make me a design” buttons or hyper-focused on design handoff. Nothing could help me actually do stuff in Figma, and anything that claimed it could proved to be unreliable.

As model context windows increased, harness developers traded efficiency and reliability for flexibility by relying on context-based guardrails like skills. Figmagent tries to approach work in Figma like work in code. If any question about the agent’s work has a clear yes/no answer then that judgment should be built into the harness instead of relying on model inference and reasoning.

This led to increased reliability on tasks like refactoring designs, auditing component sets and updating design libraries to match new code releases — things we all know we should do but never have the time for. Intern work. Figmagent is a reliable intern. I’ve found it to be super helpful. You should give it a try.

Some details of how I architected it:

Claude Code-shaped interface

I tried to mirror the structure of tools agents are already familiar with and trained on. The five-tool structure of Claude Code was adapted to structure the main tools Figmagent offers. This made it easier for the agent to know what tool to reach for — it was already familiar with the pattern.

Intent-based tools

Agents can handle greater complexity within a tool. In fact, I think they prefer it. Instead of lots of single-activity tools, agents can handle a very complex tool that maps to a single intent: search, create, mutate. Within those high-level tools they are given the ability to do lots of things tied to that intent, which yields fewer tool calls, which leads to fewer verification round-trips and more reliable work in Figma that conserves context and tokens. The agent’s superpower is to relentlessly follow an intent; tools mapped to that intent are more easily discovered and more successfully used.

Building determinism into the harness

If a certain output is always wrong, the agent shouldn’t need to check a guideline or md file to find that out. The default Figma MCP relies on agents using skills and documentation to write JavaScript to manipulate Figma files. Figmagent provides the agents with tools that handle the JS, eliminating a wide swath of potential errors. The tools also provide error feedback to the agent and input typing. It basically self-documents the tools, allowing the agent to quickly learn how to effectively make changes in Figma. They can experience Figma more like a human does: by using it, not by reading a manual and then trying to write code to manipulate the interface.

Saving model inference for the hard stuff

Certain choices can’t be automated. What component to use? Which pattern to reach for? What tokens to apply? This is where real judgment is needed, and this is where the non-deterministic reasoning capability of an agent really shines. If the context budget can be saved for this work instead of fumbling with JS and tools then the agent does better work. This is really what takes a design agent from a cool demo to something that actually has utility.

Date
2026
Designed at
Automattic
Work
Design Engineering, Agent Experience Design
Link
GitHub