Skip to content

Navigation Menu

Sign in
Sign up

Night Watch Figma Librarian

ernestt edited this page Jul 17, 2026 · 2 revisions

Night Watch — Figma Librarian

Assigned to: Ernest's Navi (ernestt)

Goal: Keep the Astryx Figma Library in sync with the code in packages/core/ — but only on stable dot releases, not on every canary commit.

Frequency: Polls daily. Requires the assignee's machine with Figma open and a Figma MCP client connected. If the machine is off, the run skips and catches up on the next available day — drift accumulates harmlessly.

GitHub repo: https://github.com/facebook/astryx

Operational specifics — Figma file key, MCP node, API endpoints, state-file paths, notification channel, and the exact command sequence — live in the assignee's private automation, not in this page. This page documents the approach only.


Why This Role Exists

The Astryx Figma library and the Astryx code library are two representations of the same design system. When a component gets a new prop, variant, size, or block example in code, the Figma library should reflect that. Left manual, this sync drifts silently — a designer builds with outdated Figma components, ships a handoff, and the engineer discovers the mismatch during implementation.

The Figma Librarian closes this loop automatically — but deliberately tracks released code, not in-flight canary changes, so the library only ever mirrors what's actually shipped.


Operating Model: Release-Gated, Checkpoint-and-Execute

This role does not diff every commit. It watches for a new published dot release and, when one lands, brings the Figma library up to that release in one pass:

poll daily
 │
 ▼
new dot release published? ── no ──▶ exit quietly
 │ yes
 ▼
read release notes ─▶ categorize Figma implications ─▶ build a plan
 │
 ▼
save Figma version-history checkpoint ◀── mandatory; if it fails, STOP (report plan only)
 │
 ▼
execute the planned edits in the file ◀── never publish
 │
 ▼
record state + log + post a run summary (with checkpoint name for revert)

Three principles hold the model together:

  1. Release-gated. Work is triggered only by a new published dot release of @astryxdesign/core, compared against the last version this role processed. No new release → no work. This keeps the library aligned with shipped code and out of sync with churny canary changes.

  2. Checkpoint before edits. Before any change, the role saves a named Figma version-history checkpoint. If the checkpoint can't be saved, it makes no edits and reports the plan only. The checkpoint is what makes the auto-execute model safe — anything can be reverted in one step.

  3. Stage, never publish. The role edits the library file but never publishes it. Publishing is the assignee's manual final gate: a human reviews the staged changes in Figma's publish dialog and either publishes or reverts to the checkpoint.

What it does

  • Gate on a new published version of the core package
  • Read the release notes for that version (GitHub release / changesets / CHANGELOG)
  • Classify each release item by its Figma implication (see categories below)
  • Read new unresolved Figma comments since the last run
  • Read the current Figma component state to measure the real gap
  • Save a version-history checkpoint before touching anything
  • Execute the planned edits: add components, add/update block examples, update variants/props, update tokens, mark removals
  • Respect human overrides — preserve manual Figma edits unless code directly conflicts
  • Post a run summary with the checkpoint name

What it does NOT do

  • Sync on canary / every-commit changes — releases only
  • Publish the Figma library — that's a human's manual step
  • Edit anything if the version-history checkpoint can't be saved
  • Visual design judgment (Designer role), code/PR review (Reviewer), CI fixes (QA), issue triage (PM), component code auditing (Component Auditor)

Reading Release Notes

Once a new version is detected, gather the full set of user-facing changes for that version — from the GitHub release, the aggregated CHANGELOG entries, and the changeset history that fed it. Changeset bodies are already categorized ([category] summary where category ∈ {breaking, component, feat, fix, perf, docs, chore}); use that as the starting signal, then map to a Figma implication below.


Categorizing Figma Implications

Classify every release item into exactly one bucket. Only the first five produce edits.

Category Trigger in release notes Figma action
NEW COMPONENT A new component/variant added to the core package Build it in the library
PROP / VARIANT CHANGE Added/removed/renamed prop, new size/state/variant value Update the component's variant axes / boolean / text / slot / instance-swap properties. Watch for a paired block example — a new prop/variant very often ships with one (see next row).
BLOCK EXAMPLE A new or changed block example (type: 'block') for a component Add or update the matching example frame in the library. Treat as its own line item even when it accompanies a prop change.
VISUAL / TOKEN CHANGE Color, spacing, typography, radius, motion, or theme change Update the corresponding Figma variables / styles
REMOVAL / DEPRECATION Component or variant removed from code Mark deprecated / remove in Figma
NO FIGMA IMPACT Internal tooling, docs, tests, build, perf, a11y wiring with no visual or API-surface change None

Code is king. Figma reflects released code, never the reverse. A comment or request for something that isn't in the code is surfaced to a human, not actioned (see Comments).

Components that are pure infrastructure — layout and context utilities with no visual representation — are skipped. If a new component looks like infrastructure (no visual props, no variant types, only children + utility props), classify it NO FIGMA IMPACT.


Prop-to-Figma Mapping

How TypeScript props map to Figma component concepts:

Code pattern Figma representation
Union type prop (variant?: 'primary' | 'secondary') Variant axis
Size union (size?: 'sm' | 'md' | 'lg') Variant axis
Boolean prop (isDisabled?: boolean) Boolean component property
String prop (label: string) Text component property
Single fixed-type ReactNode (icon?: ReactNode) Instance swap (INSTANCE_SWAP)
Freeform ReactNode (children, endContent, startContent, trigger, header) Figma Slot
Repeating ReactNode (items?: ReactNode[]) Figma Slot with repeating instances

Rule of thumb: arbitrary JSX children → Slot. A single component of a constrained type (like an icon) → Instance Swap. Use the native Figma Slot feature — never a plain frame named "Slot."

Props that do NOT map to Figma: event handlers (onClick), ref, HTML attributes (className, style, id), style overrides, as, and link behavior (href, target, rel).


Component Naming

Astryx code uses bare names — the XDS/Astryx prefix was removed. When resolving code ↔ Figma:

  • Component file: packages/core/src/{Component}/{Component}.tsx (e.g. Button/Button.tsx)
  • Props interface: {Component}Props (e.g. ButtonProps)
  • Figma component set: named for the bare component (e.g. Button)

Human Override Policy

The Figma library is a shared artifact. Designers may manually adjust components for visual reasons that don't map to code props. The role must respect this.

  • Additive code change + human edit (e.g. code adds size="xl", designer tweaked size="md" padding) → apply the additive change alongside the human's edit.
  • Direct conflict (code removed/renamed something a human customized) → code wins on what props exist, but log the conflict and flag it for review.
  • Ambiguous conflict (human and code both changed the same value) → do not auto-apply. Log and skip; let a human decide.
  • Human edit, no code change → preserve it, and record it so it isn't re-flagged next run.

The checkpoint makes all of this recoverable: if an override is clobbered by mistake, the assignee reverts to the pre-release checkpoint.


Figma Comments

Before editing, the role reads new unresolved comments on the library file and classifies each:

Signal Classification Action
A question about the component Question Reply with a factual answer citing the code (prop interface, default, variant list).
Requests something not in code ("add", "we need", "can we get") Request (no code match) Do not action. Surface for a human to decide. Code is king.
Points out a real code↔Figma gap ("code has X but Figma doesn't", "out of date") Parity Fix in Figma during execute, cite the comment. Higher priority than automated detection — a human noticed it.
Ambiguous Surface for a human Let a human classify.

Never resolve or delete comments — humans do that.


Connection Handling

If the Figma MCP connection isn't available, the role still reads the release notes and builds the plan (this works without Figma), reports the plan only, and makes no edits and no checkpoint. Crucially, it does not mark the release as processed — so the next connected run picks the release back up.


First Run

On the very first run the role has no record of a previously processed version, so it establishes a baseline (recording the current published version and reading the current Figma state as the starting point) rather than treating everything as new. Actual sync begins once a genuinely newer release lands.


Run Summary

After each run the role posts a summary that leads with the release delta (previous → new) and the checkpoint name for one-step revert, then lists the changes applied grouped by category (with block examples called out), how comments were handled, any conflicts flagged, human overrides preserved, and a clear reminder that changes are staged and awaiting a manual Publish. When there's no new release, it reports that nothing needed syncing.


Related

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /