thiagoxikota/figma-maxxing
v1.1.1MIT
Agent skills for real Figma files: Plugin API gotchas, checks before and after every write, comments to verified fixes, handoff gate.
Changelog
All notable changes to this project are documented here. The format follows Keep a Changelog and the project uses semantic versioning.
[Unreleased]
1.1.1 - 2026-10-05
Security
daemon.mjs, the opt-inmcp-directdaemon offigma-bridge-doctor, asks npm for its cache throughexecFileSyncwith a fixed argument list and no shell, instead ofexecSyncwith a command string. Cisco skill scanner 2.0.14 (--policy balanced) reported that line as CRITICALCOMMAND_INJECTION_JS_CHILD_PROCESS; after the change it reports 0 critical and 0 high findings.daemon.mjsno longer sends error text to the HTTP client (CodeQLjs/stack-trace-exposure). The client gets a fixed message per failure class, and the detail goes to the daemon's stderr. Themcp-directREADME describes both changes.- The local server recipes for loading images and saving exports (
plugin-api-data.md,plugin-api-anomalies.md,figma-comment-fix-loop) bind::1, or127.0.0.1wherelocalhostresolves only there, instead of::, which listens on every interface. The export server now comes as code inplugin-api-data.md: it keeps only the basename ofname, accepts only.pngnames and PNG bytes, and writes into one folder.Access-Control-Allow-Origin: *stays, with its reason: Figma documents that plugin iframes have anullorigin.security-canon.mdgains a section on local servers the agent starts, andPRIVACY.mdmentions the recipe.
Fixed
- Two field notes contradicted
@figma/plugin-typings1.140.0. They are qualified, not removed: writes under a locked ancestor that did not take, andsetTimeoutthat did not fire. Each now says it was seen through the figma-console bridge (figma_execute), quotes what the typings say, and gives the cause as not established.figma-preflight,docs/gotchas.md,llms.txtand both READMEs carry the same qualification. Both note headings, and so their anchors, changed. - Both READMEs: the 14 unplanted items describe 13 distinct problems (both checks flagged the same rename); the test ran on a live Figma file built for the test; the M8ven entry is described as it is (claimed by the author, public grade C (Emerging), code sub-score 100 read on 2026-10-04 at commit 1dca321); each install route says where it ran from (GitHub main at 5afe295, the v1.1.0 release, GitHub, or a local copy).
docs/works-with.md: "Demo run" no longer says "end to end". It counts what did not run as written (19 skill steps in the audit, 3 of the 8 preflight checks in the fix) and says detector 8 changed after the run. The READMEs andllms.txtsay the same.- The 1.1.0 entry below gives the limits of the 10 of 10 result in the same sentence.
fetch_comments.pyhandles a read timeout and an answer that is not JSON, and prints the first 300 bytes of an HTTP error body, never the headers. Exit codes: 1 HTTP error, 2 usage or no token, 3 network error or timeout, 4 not JSON. Tests cover each branch without network.security-canon.md:talktofigmamoves from BANNED/High, which cited no advisory, to UNVERIFIED (not evaluated here). The default deny still applies.
Changed
figma-comment-fix-looplists the exit codes offetch_comments.pyand says to keepcomments-raw.jsonout of git, because it holds commenter handles.- Portuguese README: phrases that read as translations are rewritten ("Para começar", "O que dá errado, e qual skill pega", "Dá para usar na biblioteca do time", "um checklist", "reserva o arquivo com um lock"). The "Para começar" anchor changed.
- The README gotcha list starts with the gotchas that agree with Figma's docs and keeps one qualified field note.
scripts/release_notes.pychecks every JSON manifest with a version field and the version line ofllms.txt, as its docstring says.scripts/build_dist.pysays that six of the per-skill zips needfigma-canoninstalled next to them.AGENTS.md: a "Cutting a release" section, ending with "never move a tag; ship the next patch"..codexignore: the first comment says scanners read it and Codex CLI 0.156.1 copies the whole repository regardless.- Version 1.1.1 in every manifest, every
SKILL.md,CITATION.cffandllms.txt.
1.1.0 - 2026-10-05
Added
figma-comment-fix-loop/scripts/fetch_comments.py: reads the open comments through the REST API with the token from the environment, sends it only to api.figma.com and never prints it. The skill calls it instead of an inlinecurl..codexignore, and the square icon in the Codex and Cursor listings.- Manifests for more agents, all at 1.1.0 with one shared description: a root
plugin.json(Agent Plugins 1.0.0),.codex-plugin/plugin.jsonfor Codex,.cursor-plugin/plugin.jsonfor Cursor,gemini-extension.jsonfor Gemini CLI andskills.sh.jsonfor the skills.sh page groupings. The Codex, Copilot CLI and Gemini CLI installs were run from a local copy; Cursor was not tested. docs/gotchas.md("Why does my agent...?"): every gotcha indexed by the symptom a designer sees, plus an index by literal error message. It links to the notes and never restates a fix.docs/landscape.md: a dated map of the Figma MCP servers, skill sets and catalogs, and how these skills compose with Figma's own.docs/works-with.md: which Figma connection each skill needs and how far each pair has been tested, with the blind demo on the official Figma MCP server (10 of 10 planted defects found, on one demo screen in one run; the agent that planted the defects had read the skills, and the auditor's prompt named the properties to inspect).- A
compatibilityfield in everySKILL.md, stating only real requirements. - Security text inside the skills: a Trust boundary section in
figma-canon, an Untrusted input rule infigma-orientandfigma-comment-fix-loop, and a "What it can change on your machine" section that opensfigma-bridge-doctor. figma-orientaccepts the official Figma MCP server as a read path, with a call budget.figma-bridge-doctorreferenceslayer1-recovery.md,plugin-version-drift.mdandrival-write-audit.md, moved word for word out of itsSKILL.md.scripts/check_api.pyandscripts/api-allowlist.txt: every Plugin API name in the skills is checked against@figma/plugin-typings1.140.0 (pinned, sha512 verified), including members that exist only in FigJam, Slides or Buzz.scripts/count_claims.py: every skill, gotcha and check count in the docs is recounted from the files.scripts/build_dist.py: reproducible release zips (one per skill, a plugin bundle andSHA256SUMS) read from a git commit.scripts/release_notes.py: a release fails unless the tag matches every version field and this file has the section.- CI: the Plugin API check, the claim counts, the Agent Skills reference validator, the Claude Code plugin validator, a link check (lychee), a secret scan of the full history (gitleaks) and actionlint. New workflows:
drift.yml(weekly check against the newest typings and link rot, opens an issue),release.yml(build twice, compare bytes, attach a build provenance attestation) andscorecard.yml(OpenSSF Scorecard). AGENTS.md, the contributor guide for AI agents, withCLAUDE.mdpointing to it.PRIVACY.md(no telemetry, nothing collected).CITATION.cff.- Issue forms for a rule that stopped being true and for a bug in a script, hook or installer. Discussion forms for show and tell and for gotchas, for when Discussions is turned on. A private security report link in the issue chooser.
llms.txt: the version, three agent rules (the annotations property,get_design_contextcan leave annotations out, theuse_figmaretry flag) and a section on how the rules are checked.- Tests that fail when a shipped GIF or MP4 carries text metadata: a GIF comment, plain text or XMP block, or an MP4 tag other than the encoder (location, author, device).
- Assets: a before and after image and a GIF from the blind demo, a vertical video for social posts, a social preview card and a square icon (
assets/icon.png). The banner shows the skill and gotcha counts.
Changed
- README rewritten: quick start on the first screen, the blind test before and after, a section per agent, how the repository is verified and how far it has been tested. The Portuguese prompt moved to
docs/README.pt-BR.md, which mirrors the English README. - Claude Code manifests:
$schema,displayName,documentationUrl,supportUrlandprivacyPolicyUrl; the marketplace entry gains a category (design) and tags; keywords updated; the description now says "after every write". The marketplace and plugin names are unchanged, sofigma-maxxing@figma-maxxing-skillsstill installs. - Cross-skill references are relative links (
../figma-canon/references/...), so they resolve inside the plugin layout. - Script commands in
figma-bridge-doctorandfigma-preflightuse${CLAUDE_SKILL_DIR}/scripts/.... - The
mcp-directdaemon starts only after the user says yes, and only the user installs the bridge watchdog. figma-comment-fix-loopshows the comments it will act on and waits for a yes before any write.SECURITY.md: a private advisory link, response times, supported versions and a section on themcp-directdaemon.CONTRIBUTING.md: where to post what, the API check, the changelog rule and contributing with an agent.- Dependabot runs weekly and also updates the CI Python dependencies, which are pinned by sha256. Every GitHub Action is pinned to a commit SHA.
.gitattributescounts Markdown in the language bar.- The diagram of how the skills fit together names both write tools,
use_figmaandfigma_execute. figma-canon/references/security-canon.mdcites Figma's MCP server FAQ for the seat rules: a Full seat writes outside drafts, and a Dev seat only inside its own drafts.
Fixed
- Annotations:
plugin-api-data.mdtaughtnode.getAnnotations()andfigma.setAnnotations(), which do not exist. It now uses thenode.annotationsproperty andfigma.annotations, checked against@figma/plugin-typings1.140.0. use_figmais no longer described as always atomic: on an error, obeysafeToRetryWithoutCanvasReadand read the canvas before retrying when it isfalse.figma-slop-checkdetector 8 also readsdetachedInfoon FRAME nodes. Figma turns a detached instance into a FRAME, so the rule that read only INSTANCE nodes could not see one. The blind demo found the gap; the new rule has not run since.draw-overlay.js(figma-click-flow) no longer depends onfigma.loadAllPagesAsync(), which Figma lists as not implemented inuse_figma, and checks thatreactionsandabsoluteBoundingBoxexist before reading them.
Security
daemon.mjsreadsnpm_config_cachefrom the environment before it runsnpm.- Every CI job has a read-only token, except the release job (contents, id-token, attestations), the drift job (issues) and the Scorecard job (security-events, id-token).
1.0.0 - 2026-10-01
First public release.
Added
- Eight skills:
figma-canon,figma-preflight,figma-orient,figma-slop-check,figma-handoff-gate,figma-comment-fix-loop,figma-click-flow,figma-bridge-doctor. figma-canonreferences: Plugin API core and data rules, write atomicity, auto layout, naming, state coverage, handoff format, quality rubric, AI slop signatures, inspection protocol, security, rate limits, Code Connect setup, Plugin API anomalies and field notes.- Advisory file lock for agent sessions that share a Figma file (
skills/figma-preflight/scripts/figma_lock.py). - Optional precheck hook for
figma_execute(hooks/figma-canon-precheck.py), warn mode by default. - Installer that copies skills and never overwrites (
install.py). - Claude Code plugin and marketplace manifests.
llms.txtindex for AI readers, README in English and Portuguese.- Tests and CI on macOS and Ubuntu.
llms.txt: a self-contained digest for chat AIs, with the rules any designer can use without installing anything.- Diagram of how the skills fit together, in light and dark versions.
- Code of conduct, issue forms, pull request template, Dependabot for GitHub Actions.
Security
- The
mcp-directfallback daemon accepts only local requests that carry its bearer token and a JSON content type, and refuses any request with anOriginheader. figma-bridge-doctorasks before any step that quits Figma Desktop, and its reset script never quits Figma unlessFIGMA_FULL_RESET=1is set. Without asking, it kills only orphan servers.- The advisory file lock uses an OS file lock, so a crashed session never leaves the lock directory blocked.