@fprad0/skill-master-mcp 0.0.12 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (353) hide show
  1. package/CHANGELOG.md +100 -88
  2. package/README.md +472 -472
  3. package/VERSION.md +9 -9
  4. package/bin/lib/bootstrap-global-core.mjs +34 -0
  5. package/bin/lib/client-config.mjs +287 -285
  6. package/bin/lib/doctor-core.mjs +202 -0
  7. package/bin/lib/menu-core.mjs +1792 -1514
  8. package/bin/lib/operation-result.mjs +59 -0
  9. package/bin/lib/register-clients-core.mjs +247 -0
  10. package/bin/lib/skill-installation.mjs +215 -215
  11. package/bin/lib/update-cli-core.mjs +117 -0
  12. package/bin/skill-master-activation.mjs +165 -163
  13. package/bin/skill-master-bootstrap-global.mjs +61 -49
  14. package/bin/skill-master-configure-private-registry.mjs +3 -3
  15. package/bin/skill-master-doctor.mjs +239 -228
  16. package/bin/skill-master-eval-activation.mjs +32 -32
  17. package/bin/skill-master-install-global-skills.mjs +59 -59
  18. package/bin/skill-master-install-project-skills.mjs +97 -97
  19. package/bin/skill-master-menu.mjs +489 -378
  20. package/bin/skill-master-register-clients.mjs +232 -153
  21. package/bin/skill-master-success-skills.mjs +357 -307
  22. package/bin/skill-master-update.mjs +121 -72
  23. package/bin/skill-master.mjs +3 -3
  24. package/dist/activation.d.ts.map +1 -1
  25. package/dist/activation.js +12 -0
  26. package/dist/activation.js.map +1 -1
  27. package/dist/prompt-router.d.ts.map +1 -1
  28. package/dist/prompt-router.js +19 -0
  29. package/dist/prompt-router.js.map +1 -1
  30. package/dist/recommender.d.ts.map +1 -1
  31. package/dist/recommender.js +4 -1
  32. package/dist/recommender.js.map +1 -1
  33. package/docs/architecture/APRENDIZADO_DE_IMPLEMENTACOES_BEM_SUCEDIDAS.md +125 -125
  34. package/docs/architecture/ARQUITETURA_AUTO_UPDATE.md +9 -9
  35. package/docs/architecture/PLANO_MASTER_ACIONAMENTO_AUTOMATICO_E_APRENDIZADO.md +341 -341
  36. package/docs/architecture/REDE_SEGURA_DE_SKILLS.md +148 -148
  37. package/docs/operations/GUIA_MULTI_COMPUTADOR.md +262 -262
  38. package/docs/operations/GUIA_NPM_PRIVADO.md +294 -294
  39. package/docs/operations/GUIA_NPM_PUBLICO.md +147 -147
  40. package/docs/operations/MENU_VISUAL_EVIDENCE_2026-06-28.md +66 -66
  41. package/docs/operations/assets/menu-frame-compact.html +36 -33
  42. package/docs/operations/assets/menu-frame-dna-hero.html +87 -0
  43. package/docs/operations/assets/menu-frame-fine-helix.html +89 -0
  44. package/docs/operations/assets/menu-frame-large.html +44 -41
  45. package/docs/operations/assets/menu-frame-running.html +41 -38
  46. package/docs/operations/assets/menu-frame-score-10-contact-sheet.html +184 -0
  47. package/docs/operations/cross-platform-auth-transfer/ANALISE_COMPATIBILIDADE_MCP_2026-06-28.md +140 -140
  48. package/docs/operations/cross-platform-auth-transfer/README_TRANSFERENCIA.md +85 -85
  49. package/docs/operations/reborn-menu-cyberpunk-transfer/ANALISE_MENU_REBORN_CYBERPUNK_2026-06-28.md +174 -174
  50. package/docs/operations/reborn-menu-cyberpunk-transfer/HANDOFF_IMPLEMENTACAO_REBORN_CYBERPUNK_2026-06-28.md +119 -119
  51. package/docs/operations/reborn-menu-cyberpunk-transfer/ORDEM_DE_EXECUCAO_MENU_REBORN_CYBERPUNK.md +134 -134
  52. package/docs/operations/reborn-menu-cyberpunk-transfer/README_TRANSFERENCIA.md +84 -84
  53. package/docs/operations/reborn-menu-cyberpunk-transfer/README_TRANSFERENCIA_REBORN_PACKAGE.md +56 -56
  54. package/docs/operations/token-economy-transfer/ANALISE_AVANCADA_ECONOMIA_TOKENS_2026-06-30.md +141 -0
  55. package/docs/operations/token-economy-transfer/PLANO_DEV_SENIOR_MASTER_TOKEN_ECONOMY_2026-06-30.md +171 -0
  56. package/docs/operations/token-economy-transfer/README_TRANSFERENCIA_TOKEN_ECONOMY.md +31 -0
  57. package/docs/planning/MENU_RUNTIME_CORRECTION_PLAN_2026-06-30.md +551 -0
  58. package/docs/planning/V0_0_9_APROVACAO_CRITICA_MENSAGENS_DE_VENDA.md +85 -85
  59. package/docs/planning/V0_0_9_FONTES_E_CRITERIOS_DE_AUTORIDADE.md +139 -139
  60. package/docs/planning/V0_0_9_MATRIZ_SKILLS_MULTIDISCIPLINARES.md +105 -105
  61. package/docs/planning/V0_0_9_POLITICA_MORAL_CATOLICA_PARA_IA.md +181 -181
  62. package/docs/planning/V0_0_9_PROMPTS_EXECUCAO.md +59 -59
  63. package/docs/planning/V0_0_9_ROADMAP_DISCERNIMENTO_E_CONHECIMENTO_AMPLO.md +181 -181
  64. package/docs/planning/mcp-1.0.0/00_RESUMO_EXECUTIVO_AUDITORIA_MENU.md +118 -0
  65. package/docs/planning/mcp-1.0.0/01_MATRIZ_TESTES_MENU_E_RESULTADOS.md +250 -0
  66. package/docs/planning/mcp-1.0.0/02_PLANO_CORRECAO_ATIVAR_SKILL_APRENDIDA.md +200 -0
  67. package/docs/planning/mcp-1.0.0/03_PLANO_COMPATIBILIDADE_WINDOWS_LINUX_MACOS.md +167 -0
  68. package/docs/planning/mcp-1.0.0/04_PLANO_UI_CYBERPUNK_PIXEL_ART_E_PERFORMANCE.md +165 -0
  69. package/docs/planning/mcp-1.0.0/05_PROMPT_TASK_EXECUCAO_CORRECOES.md +151 -0
  70. package/docs/planning/mcp-1.0.0/06_CHECKLIST_REGRESSAO_PRE_RELEASE.md +159 -0
  71. package/docs/planning/mcp-1.0.0/07_RELATORIO_APLICACAO_CORRECOES_MENU_SKILL_MASTER.md +136 -0
  72. package/docs/planning/mcp-1.0.0/08_AUDITORIA_CRITICA_MENU_NOTA_E_DNA_REFINADO.md +184 -0
  73. package/docs/planning/mcp-1.0.0/prompt-tasks-nota-10-10/00_PROMPT_TASK_MASTER_NOTA_10_10.md +103 -0
  74. package/docs/planning/mcp-1.0.0/prompt-tasks-nota-10-10/01_PROMPT_TASK_FINE_HELIX_DNA.md +116 -0
  75. package/docs/planning/mcp-1.0.0/prompt-tasks-nota-10-10/02_PROMPT_TASK_DNA_HERO_BOOT_AND_MOTION.md +109 -0
  76. package/docs/planning/mcp-1.0.0/prompt-tasks-nota-10-10/03_PROMPT_TASK_MENU_UX_HELP_ERROR_COPY.md +99 -0
  77. package/docs/planning/mcp-1.0.0/prompt-tasks-nota-10-10/04_PROMPT_TASK_EVIDENCE_RENDERER_1_0_0.md +97 -0
  78. package/docs/planning/mcp-1.0.0/prompt-tasks-nota-10-10/05_PROMPT_TASK_CROSS_PLATFORM_UTF8_MOJIBAKE.md +99 -0
  79. package/docs/planning/mcp-1.0.0/prompt-tasks-nota-10-10/06_PROMPT_TASK_VISUAL_REGRESSION_QA.md +105 -0
  80. package/docs/planning/mcp-1.0.0/prompt-tasks-nota-10-10/07_PROMPT_TASK_PRE_RELEASE_SCORE_GATE_10_10.md +104 -0
  81. package/docs/planning/mcp-1.0.0/prompt-tasks-nota-10-10/README_ORDEM_EXECUCAO_NOTA_10_10.md +77 -0
  82. package/docs/prompt-tasks/PROMPT_TASK_001_BOOTSTRAP_SKILL_MASTER_MCP.md +6 -6
  83. package/docs/prompt-tasks/PROMPT_TASK_002_AUTO_UPDATE_LAUNCHER.md +6 -6
  84. package/docs/prompt-tasks/PROMPT_TASK_003_REMOTE_MANIFEST_AND_RELEASES.md +6 -6
  85. package/docs/prompt-tasks/PROMPT_TASK_004_MULTI_USER_DISTRIBUTION.md +6 -6
  86. package/docs/prompt-tasks/PROMPT_TASK_005_SECURITY_AND_QUALITY_GATE.md +6 -6
  87. package/docs/prompt-tasks/PROMPT_TASK_006_MASTER_ACIONAMENTO_APRENDIZADO.md +83 -83
  88. package/docs/prompt-tasks/PROMPT_TASK_007_PERSONA_ORQUESTRADORA.md +88 -88
  89. package/docs/prompt-tasks/PROMPT_TASK_008_PROMPT_ROUTER_MODOS_ATIVACAO.md +156 -156
  90. package/docs/prompt-tasks/PROMPT_TASK_009_PIPELINE_APRENDIZADO_SUCESSO.md +105 -105
  91. package/docs/prompt-tasks/PROMPT_TASK_010_EVALS_GOVERNANCA_ATIVACAO.md +119 -119
  92. package/docs/prompt-tasks/PROMPT_TASK_011_MENU_NOTIFICACOES_NOTION.md +120 -120
  93. package/docs/prompt-tasks/PROMPT_TASK_012_MENU_CYBERPUNK_PIXEL_FRAME.md +123 -123
  94. package/docs/prompt-tasks/PROMPT_TASK_013_MENU_FLUID_DNA_ANIMATION.md +114 -114
  95. package/docs/prompt-tasks/PROMPT_TASK_014_MENU_FUNCTIONAL_PARITY_QA.md +157 -157
  96. package/docs/prompt-tasks/PROMPT_TASK_015_TRANSFER_RELEASE_HANDOFF.md +127 -127
  97. package/docs/prompt-tasks/PROMPT_TASK_016_CROSS_PLATFORM_MCP_AUTH_REGISTRATION.md +107 -107
  98. package/docs/prompt-tasks/PROMPT_TASK_018_NPM_PUBLISH_2FA_SETUP.md +80 -80
  99. package/docs/prompt-tasks/PROMPT_TASK_019_TOKEN_ECONOMY_GLOBAL_SKILLS.md +56 -0
  100. package/docs/prompt-tasks/PROMPT_TASK_MASTER_EXECUTOR.md +6 -6
  101. package/docs/skill-candidates/v0.0.10/cli-creator/LICENSE.txt +201 -201
  102. package/docs/skill-candidates/v0.0.10/cli-creator/SKILL.md +160 -160
  103. package/docs/skill-candidates/v0.0.10/cli-creator/agents/openai.yaml +4 -4
  104. package/docs/skill-candidates/v0.0.10/cli-creator/references/agent-cli-patterns.md +154 -154
  105. package/docs/skill-candidates/v0.0.10/developer-workstation-ops/SKILL.md +32 -32
  106. package/docs/skill-candidates/v0.0.10/figma/LICENSE.txt +1 -1
  107. package/docs/skill-candidates/v0.0.10/figma/SKILL.md +42 -42
  108. package/docs/skill-candidates/v0.0.10/figma/agents/openai.yaml +14 -14
  109. package/docs/skill-candidates/v0.0.10/figma/assets/figma-small.svg +3 -3
  110. package/docs/skill-candidates/v0.0.10/figma/assets/icon.svg +28 -28
  111. package/docs/skill-candidates/v0.0.10/figma/references/figma-mcp-config.md +35 -35
  112. package/docs/skill-candidates/v0.0.10/figma/references/figma-tools-and-prompts.md +34 -34
  113. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/LICENSE.TXT +1 -1
  114. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/SKILL.md +349 -349
  115. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/agents/openai.yaml +14 -14
  116. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/assets/figma-small.svg +3 -3
  117. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/assets/icon.svg +28 -28
  118. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/references/mapping-checklist.md +7 -7
  119. package/docs/skill-candidates/v0.0.10/figma-code-connect-components/scripts/normalize_node_id.py +25 -25
  120. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/LICENSE.TXT +1 -1
  121. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/SKILL.md +537 -537
  122. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/agents/openai.yaml +14 -14
  123. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/assets/figma-small.svg +3 -3
  124. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/assets/icon.svg +28 -28
  125. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/references/rule-template.md +15 -15
  126. package/docs/skill-candidates/v0.0.10/figma-create-design-system-rules/scripts/check_agents_md.sh +9 -9
  127. package/docs/skill-candidates/v0.0.10/figma-generate-design/LICENSE.TXT +1 -1
  128. package/docs/skill-candidates/v0.0.10/figma-generate-design/SKILL.md +341 -341
  129. package/docs/skill-candidates/v0.0.10/figma-generate-design/agents/openai.yaml +14 -14
  130. package/docs/skill-candidates/v0.0.10/figma-generate-design/assets/figma-small.svg +3 -3
  131. package/docs/skill-candidates/v0.0.10/figma-generate-design/assets/icon.svg +28 -28
  132. package/docs/skill-candidates/v0.0.10/figma-generate-design/maintainers.yml +1 -1
  133. package/docs/skill-candidates/v0.0.10/figma-generate-library/LICENSE.TXT +1 -1
  134. package/docs/skill-candidates/v0.0.10/figma-generate-library/SKILL.md +314 -314
  135. package/docs/skill-candidates/v0.0.10/figma-generate-library/agents/openai.yaml +14 -14
  136. package/docs/skill-candidates/v0.0.10/figma-generate-library/assets/figma-small.svg +3 -3
  137. package/docs/skill-candidates/v0.0.10/figma-generate-library/assets/icon.svg +28 -28
  138. package/docs/skill-candidates/v0.0.10/figma-generate-library/maintainers.yml +3 -3
  139. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/code-connect-setup.md +260 -260
  140. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/component-creation.md +1014 -1014
  141. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/discovery-phase.md +518 -518
  142. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/documentation-creation.md +834 -834
  143. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/error-recovery.md +540 -540
  144. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/naming-conventions.md +527 -527
  145. package/docs/skill-candidates/v0.0.10/figma-generate-library/references/token-creation.md +962 -962
  146. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/bindVariablesToComponent.js +110 -110
  147. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/cleanupOrphans.js +127 -127
  148. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createComponentWithVariants.js +148 -148
  149. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createDocumentationPage.js +139 -139
  150. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createSemanticTokens.js +108 -108
  151. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/createVariableCollection.js +49 -49
  152. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/inspectFileStructure.js +121 -121
  153. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/rehydrateState.js +92 -92
  154. package/docs/skill-candidates/v0.0.10/figma-generate-library/scripts/validateCreation.js +83 -83
  155. package/docs/skill-candidates/v0.0.10/figma-implement-design/LICENSE.txt +1 -1
  156. package/docs/skill-candidates/v0.0.10/figma-implement-design/SKILL.md +258 -258
  157. package/docs/skill-candidates/v0.0.10/figma-implement-design/agents/openai.yaml +14 -14
  158. package/docs/skill-candidates/v0.0.10/figma-implement-design/assets/figma-small.svg +3 -3
  159. package/docs/skill-candidates/v0.0.10/figma-implement-design/assets/icon.svg +28 -28
  160. package/docs/skill-candidates/v0.0.10/figma-use/LICENSE.TXT +1 -1
  161. package/docs/skill-candidates/v0.0.10/figma-use/SKILL.md +233 -233
  162. package/docs/skill-candidates/v0.0.10/figma-use/agents/openai.yaml +14 -14
  163. package/docs/skill-candidates/v0.0.10/figma-use/assets/figma-small.svg +3 -3
  164. package/docs/skill-candidates/v0.0.10/figma-use/assets/icon.svg +28 -28
  165. package/docs/skill-candidates/v0.0.10/figma-use/maintainers.yml +1 -1
  166. package/docs/skill-candidates/v0.0.10/figma-use/references/api-reference.md +301 -301
  167. package/docs/skill-candidates/v0.0.10/figma-use/references/common-patterns.md +512 -512
  168. package/docs/skill-candidates/v0.0.10/figma-use/references/component-patterns.md +488 -488
  169. package/docs/skill-candidates/v0.0.10/figma-use/references/effect-style-patterns.md +123 -123
  170. package/docs/skill-candidates/v0.0.10/figma-use/references/gotchas.md +599 -599
  171. package/docs/skill-candidates/v0.0.10/figma-use/references/maintainers.yml +12 -12
  172. package/docs/skill-candidates/v0.0.10/figma-use/references/plugin-api-patterns.md +513 -513
  173. package/docs/skill-candidates/v0.0.10/figma-use/references/plugin-api-standalone.d.ts +11293 -11293
  174. package/docs/skill-candidates/v0.0.10/figma-use/references/plugin-api-standalone.index.md +441 -441
  175. package/docs/skill-candidates/v0.0.10/figma-use/references/text-style-patterns.md +203 -203
  176. package/docs/skill-candidates/v0.0.10/figma-use/references/validation-and-recovery.md +109 -109
  177. package/docs/skill-candidates/v0.0.10/figma-use/references/variable-patterns.md +354 -354
  178. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/maintainers.yml +9 -9
  179. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-components--creating.md +17 -17
  180. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-components--using.md +17 -17
  181. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-components.md +50 -50
  182. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-effect-styles.md +52 -52
  183. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-text-styles.md +90 -90
  184. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-variables--creating.md +13 -13
  185. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-variables--using.md +13 -13
  186. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds-variables.md +64 -64
  187. package/docs/skill-candidates/v0.0.10/figma-use/references/working-with-design-systems/wwds.md +41 -41
  188. package/docs/skill-candidates/v0.0.10/frontend-design/LICENSE.txt +177 -177
  189. package/docs/skill-candidates/v0.0.10/frontend-design/SKILL.md +55 -55
  190. package/docs/skill-candidates/v0.0.10/frontend-ui-ux-systems/SKILL.md +32 -32
  191. package/docs/skill-candidates/v0.0.10/github/SKILL.md +74 -74
  192. package/docs/skill-candidates/v0.0.10/github/agents/openai.yaml +6 -6
  193. package/docs/skill-candidates/v0.0.10/github/assets/github-small.svg +3 -3
  194. package/docs/skill-candidates/v0.0.10/image-graphic-design-rendering/SKILL.md +28 -28
  195. package/docs/skill-candidates/v0.0.10/language-quality-pt-en-fr-it-ru/SKILL.md +28 -28
  196. package/docs/skill-candidates/v0.0.10/math-physics-reasoning/SKILL.md +28 -28
  197. package/docs/skill-candidates/v0.0.10/mcp-builder/LICENSE.txt +201 -201
  198. package/docs/skill-candidates/v0.0.10/mcp-builder/SKILL.md +236 -236
  199. package/docs/skill-candidates/v0.0.10/mcp-builder/reference/evaluation.md +601 -601
  200. package/docs/skill-candidates/v0.0.10/mcp-builder/reference/mcp_best_practices.md +249 -249
  201. package/docs/skill-candidates/v0.0.10/mcp-builder/reference/node_mcp_server.md +969 -969
  202. package/docs/skill-candidates/v0.0.10/mcp-builder/reference/python_mcp_server.md +718 -718
  203. package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/connections.py +151 -151
  204. package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/evaluation.py +373 -373
  205. package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/example_evaluation.xml +22 -22
  206. package/docs/skill-candidates/v0.0.10/mcp-builder/scripts/requirements.txt +2 -2
  207. package/docs/skill-candidates/v0.0.10/mcp-client-readiness/SKILL.md +31 -31
  208. package/docs/skill-candidates/v0.0.10/openai-docs/LICENSE.txt +201 -201
  209. package/docs/skill-candidates/v0.0.10/openai-docs/SKILL.md +161 -161
  210. package/docs/skill-candidates/v0.0.10/openai-docs/agents/openai.yaml +14 -14
  211. package/docs/skill-candidates/v0.0.10/openai-docs/assets/openai-small.svg +3 -3
  212. package/docs/skill-candidates/v0.0.10/openai-docs/references/latest-model.md +37 -37
  213. package/docs/skill-candidates/v0.0.10/openai-docs/references/prompting-guide.md +244 -244
  214. package/docs/skill-candidates/v0.0.10/openai-docs/references/upgrade-guide.md +181 -181
  215. package/docs/skill-candidates/v0.0.10/openai-docs/scripts/fetch-codex-manual.mjs +598 -598
  216. package/docs/skill-candidates/v0.0.10/openai-docs/scripts/resolve-latest-model-info.js +147 -147
  217. package/docs/skill-candidates/v0.0.10/playwright/NOTICE.txt +14 -14
  218. package/docs/skill-candidates/v0.0.10/playwright/SKILL.md +147 -147
  219. package/docs/skill-candidates/v0.0.10/playwright/agents/openai.yaml +6 -6
  220. package/docs/skill-candidates/v0.0.10/playwright/assets/playwright-small.svg +3 -3
  221. package/docs/skill-candidates/v0.0.10/playwright/references/cli.md +116 -116
  222. package/docs/skill-candidates/v0.0.10/playwright/references/workflows.md +95 -95
  223. package/docs/skill-candidates/v0.0.10/playwright/scripts/playwright_cli.sh +25 -25
  224. package/docs/skill-candidates/v0.0.10/polyglot-backend-engineering/SKILL.md +32 -32
  225. package/docs/skill-candidates/v0.0.10/screenshot/LICENSE.txt +201 -201
  226. package/docs/skill-candidates/v0.0.10/screenshot/SKILL.md +267 -267
  227. package/docs/skill-candidates/v0.0.10/screenshot/agents/openai.yaml +6 -6
  228. package/docs/skill-candidates/v0.0.10/screenshot/assets/screenshot-small.svg +5 -5
  229. package/docs/skill-candidates/v0.0.10/screenshot/scripts/ensure_macos_permissions.sh +54 -54
  230. package/docs/skill-candidates/v0.0.10/screenshot/scripts/macos_display_info.swift +22 -22
  231. package/docs/skill-candidates/v0.0.10/screenshot/scripts/macos_permissions.swift +40 -40
  232. package/docs/skill-candidates/v0.0.10/screenshot/scripts/macos_window_info.swift +126 -126
  233. package/docs/skill-candidates/v0.0.10/screenshot/scripts/take_screenshot.ps1 +163 -163
  234. package/docs/skill-candidates/v0.0.10/screenshot/scripts/take_screenshot.py +585 -585
  235. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/SKILL.md +62 -62
  236. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/agents/openai.yaml +4 -4
  237. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/references/activation-policy.md +77 -77
  238. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/references/human-approval-policy.md +83 -83
  239. package/docs/skill-candidates/v0.0.10/skill-master-orchestrator/references/persona-dev-senior-master.md +46 -46
  240. package/docs/skill-candidates/v0.0.10/terminal-menu-operations/SKILL.md +30 -30
  241. package/docs/skill-candidates/v0.0.10/terminal-pixel-art-tui/SKILL.md +43 -43
  242. package/docs/skill-candidates/v0.0.10/webapp-testing/LICENSE.txt +201 -201
  243. package/docs/skill-candidates/v0.0.10/webapp-testing/SKILL.md +95 -95
  244. package/docs/skill-candidates/v0.0.10/webapp-testing/examples/console_logging.py +34 -34
  245. package/docs/skill-candidates/v0.0.10/webapp-testing/examples/element_discovery.py +39 -39
  246. package/docs/skill-candidates/v0.0.10/webapp-testing/examples/static_html_automation.py +32 -32
  247. package/docs/skill-candidates/v0.0.10/webapp-testing/scripts/with_server.py +105 -105
  248. package/docs/skill-candidates/v0.0.10/winui-app/LICENSE.txt +201 -201
  249. package/docs/skill-candidates/v0.0.10/winui-app/SKILL.md +94 -94
  250. package/docs/skill-candidates/v0.0.10/winui-app/agents/openai.yaml +5 -5
  251. package/docs/skill-candidates/v0.0.10/winui-app/config.yaml +50 -50
  252. package/docs/skill-candidates/v0.0.10/winui-app/references/_sections.md +96 -96
  253. package/docs/skill-candidates/v0.0.10/winui-app/references/accessibility-input-and-localization.md +51 -51
  254. package/docs/skill-candidates/v0.0.10/winui-app/references/build-run-and-launch-verification.md +72 -72
  255. package/docs/skill-candidates/v0.0.10/winui-app/references/community-toolkit-controls-and-helpers.md +57 -57
  256. package/docs/skill-candidates/v0.0.10/winui-app/references/controls-layout-and-adaptive-ui.md +84 -84
  257. package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-environment-audit-and-remediation.md +82 -82
  258. package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-setup-and-project-selection.md +67 -67
  259. package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-template-first-recovery.md +62 -62
  260. package/docs/skill-candidates/v0.0.10/winui-app/references/foundation-winui-app-structure.md +62 -62
  261. package/docs/skill-candidates/v0.0.10/winui-app/references/motion-animations-and-polish.md +45 -45
  262. package/docs/skill-candidates/v0.0.10/winui-app/references/performance-diagnostics-and-responsiveness.md +46 -46
  263. package/docs/skill-candidates/v0.0.10/winui-app/references/sample-source-map.md +37 -37
  264. package/docs/skill-candidates/v0.0.10/winui-app/references/shell-navigation-and-windowing.md +67 -67
  265. package/docs/skill-candidates/v0.0.10/winui-app/references/styling-theming-materials-and-icons.md +71 -71
  266. package/docs/skill-candidates/v0.0.10/winui-app/references/testing-debugging-and-review-checklists.md +77 -77
  267. package/docs/skill-candidates/v0.0.10/winui-app/references/windows-app-sdk-lifecycle-notifications-and-deployment.md +52 -52
  268. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/SKILL.md +398 -398
  269. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/common-patterns.md +330 -330
  270. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/complete-examples.md +871 -871
  271. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/component-patterns.md +501 -501
  272. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/data-fetching.md +766 -766
  273. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/file-organization.md +501 -501
  274. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/loading-and-error-states.md +500 -500
  275. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/performance.md +405 -405
  276. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/routing-guide.md +363 -363
  277. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/styling-guide.md +427 -427
  278. package/docs/skill-candidates/v0.0.11/frontend-dev-guidelines/resources/typescript-standards.md +417 -417
  279. package/docs/skill-candidates/v0.0.11/git-version-control-ops/SKILL.md +34 -34
  280. package/docs/skill-candidates/v0.0.11/go-engineering/SKILL.md +34 -34
  281. package/docs/skill-candidates/v0.0.11/java-engineering/SKILL.md +34 -34
  282. package/docs/skill-candidates/v0.0.11/javascript-engineering/SKILL.md +34 -34
  283. package/docs/skill-candidates/v0.0.11/json-contract-design/SKILL.md +34 -34
  284. package/docs/skill-candidates/v0.0.11/multi-client-mcp-ops/SKILL.md +36 -36
  285. package/docs/skill-candidates/v0.0.11/nextjs/SKILL.md +745 -745
  286. package/docs/skill-candidates/v0.0.11/nextjs/agents/openai.yaml +3 -3
  287. package/docs/skill-candidates/v0.0.11/nextjs/references/app-router-files.md +94 -94
  288. package/docs/skill-candidates/v0.0.11/python-engineering/SKILL.md +34 -34
  289. package/docs/skill-candidates/v0.0.11/ruby-engineering/SKILL.md +34 -34
  290. package/docs/skill-candidates/v0.0.11/senior-fullstack/SKILL.md +209 -209
  291. package/docs/skill-candidates/v0.0.11/senior-fullstack/references/architecture_patterns.md +103 -103
  292. package/docs/skill-candidates/v0.0.11/senior-fullstack/references/development_workflows.md +103 -103
  293. package/docs/skill-candidates/v0.0.11/senior-fullstack/references/tech_stack_guide.md +103 -103
  294. package/docs/skill-candidates/v0.0.11/senior-fullstack/scripts/code_quality_analyzer.py +114 -114
  295. package/docs/skill-candidates/v0.0.11/senior-fullstack/scripts/fullstack_scaffolder.py +114 -114
  296. package/docs/skill-candidates/v0.0.11/senior-fullstack/scripts/project_scaffolder.py +114 -114
  297. package/docs/skill-candidates/v0.0.11/shadcn/SKILL.md +573 -573
  298. package/docs/skill-candidates/v0.0.11/shadcn/agents/openai.yaml +3 -3
  299. package/docs/skill-candidates/v0.0.11/sql-postgresql-engineering/SKILL.md +34 -34
  300. package/docs/skill-candidates/v0.0.11/terminal-shell-ops/SKILL.md +34 -34
  301. package/docs/skill-candidates/v0.0.11/typescript-expert/SKILL.md +429 -429
  302. package/docs/skill-candidates/v0.0.11/typescript-expert/references/tsconfig-strict.json +91 -91
  303. package/docs/skill-candidates/v0.0.11/typescript-expert/references/typescript-cheatsheet.md +383 -383
  304. package/docs/skill-candidates/v0.0.11/typescript-expert/references/utility-types.ts +335 -335
  305. package/docs/skill-candidates/v0.0.11/typescript-expert/scripts/ts_diagnostic.py +203 -203
  306. package/docs/skill-candidates/v0.0.11/ui-component-primitives/SKILL.md +34 -34
  307. package/docs/skill-candidates/v0.0.11/web-mobile-design-systems/SKILL.md +34 -34
  308. package/docs/skill-candidates/v0.0.11/windows-linux-platform-ops/SKILL.md +34 -34
  309. package/docs/skill-candidates/v0.0.12/context-compression-handoff/SKILL.md +47 -0
  310. package/docs/skill-candidates/v0.0.12/csharp-senior-master-engineering/SKILL.md +32 -32
  311. package/docs/skill-candidates/v0.0.12/css-senior-master-engineering/SKILL.md +32 -32
  312. package/docs/skill-candidates/v0.0.12/go-senior-master-engineering/SKILL.md +32 -32
  313. package/docs/skill-candidates/v0.0.12/html-senior-master-engineering/SKILL.md +32 -32
  314. package/docs/skill-candidates/v0.0.12/javascript-senior-master-engineering/SKILL.md +32 -32
  315. package/docs/skill-candidates/v0.0.12/json-senior-master-engineering/SKILL.md +32 -32
  316. package/docs/skill-candidates/v0.0.12/prompt-budget-gate/SKILL.md +46 -0
  317. package/docs/skill-candidates/v0.0.12/python-senior-master-engineering/SKILL.md +32 -32
  318. package/docs/skill-candidates/v0.0.12/react-senior-master-engineering/SKILL.md +32 -32
  319. package/docs/skill-candidates/v0.0.12/ruby-senior-master-engineering/SKILL.md +32 -32
  320. package/docs/skill-candidates/v0.0.12/senior-master-code-optimizer/SKILL.md +48 -48
  321. package/docs/skill-candidates/v0.0.12/sql-senior-master-engineering/SKILL.md +31 -31
  322. package/docs/skill-candidates/v0.0.12/token-economy-orchestrator/SKILL.md +38 -0
  323. package/docs/skill-candidates/v0.0.12/typescript-senior-master-engineering/SKILL.md +35 -35
  324. package/docs/skill-candidates/v0.0.9/ai-ethics-human-dignity/SKILL.md +32 -32
  325. package/docs/skill-candidates/v0.0.9/broad-domain-router/SKILL.md +41 -41
  326. package/docs/skill-candidates/v0.0.9/catholic-moral-discernment/SKILL.md +31 -31
  327. package/docs/skill-candidates/v0.0.9/engineering-systems-master/SKILL.md +31 -31
  328. package/docs/skill-candidates/v0.0.9/language-quality-pt-en-fr/SKILL.md +28 -28
  329. package/docs/skill-candidates/v0.0.9/math-science-reasoning/SKILL.md +29 -29
  330. package/docs/skill-candidates/v0.0.9/philosophy-sociology-discernment/SKILL.md +28 -28
  331. package/docs/skill-candidates/v0.0.9/professional-boundary-triage/SKILL.md +40 -40
  332. package/docs/skill-candidates/v0.0.9/release-ethics-gate/SKILL.md +32 -32
  333. package/docs/skill-candidates/v0.0.9/source-authority-reviewer/SKILL.md +31 -31
  334. package/examples/client-configs/claude-code.commands.md +21 -21
  335. package/examples/client-configs/claude-code.project.mcp.json +18 -18
  336. package/examples/client-configs/claude-desktop.macos.json +18 -18
  337. package/examples/client-configs/claude-desktop.windows.json +20 -20
  338. package/examples/client-configs/codex.windows.toml +11 -11
  339. package/examples/client-configs/gemini-code-assist.intellij.mcp.json +18 -18
  340. package/examples/client-configs/gemini.linux.settings.json +21 -21
  341. package/examples/client-configs/gemini.windows.settings.json +23 -23
  342. package/examples/client-configs/generic-stdio.json +16 -16
  343. package/manifests/channels/beta.json +24 -24
  344. package/manifests/channels/stable.json +25 -25
  345. package/network/approved-skills.json +54 -54
  346. package/network/unapproved-skill-candidates.json +110 -110
  347. package/package.json +89 -86
  348. package/scripts/configure-private-registry.mjs +208 -208
  349. package/scripts/lib/private-registry.mjs +97 -97
  350. package/scripts/render-menu-evidence.mjs +196 -130
  351. package/scripts/verify-menu-actions.mjs +112 -107
  352. package/scripts/verify-menu-visual.mjs +90 -0
  353. package/sources.json +11 -11
@@ -1,512 +1,512 @@
1
- # Common Patterns
2
-
3
- > Part of the [use_figma skill](../SKILL.md). Working code examples for frequently used operations.
4
-
5
- ## Contents
6
-
7
- - Basic Script Structure
8
- - Create a Styled Shape
9
- - Create a Text Node
10
- - Create Frame with Auto-Layout
11
- - Create Variable Collections and Bindings
12
- - Create Components and Import by Key
13
- - Component Sets with Variable Modes
14
- - Multi-Step Large ComponentSet Pattern
15
- - Read Existing Nodes and Return Data
16
-
17
-
18
- ## Basic Script Structure
19
-
20
- ```js
21
- (async () => {
22
- try {
23
- const createdNodeIds = []
24
- const mutatedNodeIds = []
25
-
26
- // Your code here — track every node you create or mutate
27
- // createdNodeIds.push(newNode.id)
28
- // mutatedNodeIds.push(existingNode.id)
29
-
30
- figma.closePlugin(JSON.stringify({
31
- success: true,
32
- createdNodeIds,
33
- mutatedNodeIds,
34
- // Plus any other useful data for subsequent calls
35
- count: createdNodeIds.length
36
- }))
37
- } catch (e) {
38
- figma.closePluginWithFailure(e.toString())
39
- }
40
- })()
41
- ```
42
-
43
- ## Create a Styled Shape
44
-
45
- ```js
46
- (async () => {
47
- try {
48
- // Find clear space to the right of existing content
49
- const page = figma.currentPage
50
- let maxX = 0
51
- for (const child of page.children) {
52
- maxX = Math.max(maxX, child.x + child.width)
53
- }
54
-
55
- const rect = figma.createRectangle()
56
- rect.name = "Blue Box"
57
- rect.resize(200, 100)
58
- rect.fills = [{ type: 'SOLID', color: { r: 0.047, g: 0.549, b: 0.914 } }]
59
- rect.cornerRadius = 8
60
- rect.x = maxX + 100 // offset from existing content
61
- rect.y = 0
62
- figma.currentPage.appendChild(rect)
63
- figma.closePlugin(JSON.stringify({ nodeId: rect.id }))
64
- } catch (e) {
65
- figma.closePluginWithFailure(e.toString())
66
- }
67
- })()
68
- ```
69
-
70
- ## Create a Text Node
71
-
72
- ```js
73
- (async () => {
74
- try {
75
- // Find clear space to the right of existing content
76
- const page = figma.currentPage
77
- let maxX = 0
78
- for (const child of page.children) {
79
- maxX = Math.max(maxX, child.x + child.width)
80
- }
81
-
82
- await figma.loadFontAsync({ family: "Inter", style: "Regular" })
83
- const text = figma.createText()
84
- text.characters = "Hello World"
85
- text.fontSize = 16
86
- text.fills = [{ type: 'SOLID', color: { r: 0, g: 0, b: 0 } }]
87
- text.textAutoResize = 'WIDTH_AND_HEIGHT'
88
- text.x = maxX + 100
89
- text.y = 0
90
- figma.currentPage.appendChild(text)
91
- figma.closePlugin(JSON.stringify({ nodeId: text.id }))
92
- } catch (e) {
93
- figma.closePluginWithFailure(e.toString())
94
- }
95
- })()
96
- ```
97
-
98
- ## Create Frame with Auto-Layout
99
-
100
- ```js
101
- (async () => {
102
- try {
103
- // Find clear space to the right of existing content
104
- const page = figma.currentPage
105
- let maxX = 0
106
- for (const child of page.children) {
107
- maxX = Math.max(maxX, child.x + child.width)
108
- }
109
-
110
- const frame = figma.createFrame()
111
- frame.name = "Card"
112
- frame.layoutMode = 'VERTICAL'
113
- frame.primaryAxisAlignItems = 'MIN'
114
- frame.counterAxisAlignItems = 'MIN'
115
- frame.paddingLeft = 16
116
- frame.paddingRight = 16
117
- frame.paddingTop = 12
118
- frame.paddingBottom = 12
119
- frame.itemSpacing = 8
120
- frame.layoutSizingHorizontal = 'HUG'
121
- frame.layoutSizingVertical = 'HUG'
122
- frame.fills = [{ type: 'SOLID', color: { r: 1, g: 1, b: 1 } }]
123
- frame.cornerRadius = 8
124
- frame.x = maxX + 100
125
- frame.y = 0
126
- figma.currentPage.appendChild(frame)
127
- figma.closePlugin(JSON.stringify({ nodeId: frame.id }))
128
- } catch (e) {
129
- figma.closePluginWithFailure(e.toString())
130
- }
131
- })()
132
- ```
133
-
134
- ## Create Variable Collection with Multiple Modes
135
-
136
- ```js
137
- (async () => {
138
- try {
139
- const collection = figma.variables.createVariableCollection("Theme/Colors")
140
- // Rename the default mode
141
- collection.renameMode(collection.modes[0].modeId, "Light")
142
- const darkModeId = collection.addMode("Dark")
143
- const lightModeId = collection.modes[0].modeId
144
-
145
- const bgVar = figma.variables.createVariable("bg", collection, "COLOR")
146
- bgVar.setValueForMode(lightModeId, { r: 1, g: 1, b: 1, a: 1 })
147
- bgVar.setValueForMode(darkModeId, { r: 0.1, g: 0.1, b: 0.1, a: 1 })
148
-
149
- const textVar = figma.variables.createVariable("text", collection, "COLOR")
150
- textVar.setValueForMode(lightModeId, { r: 0, g: 0, b: 0, a: 1 })
151
- textVar.setValueForMode(darkModeId, { r: 1, g: 1, b: 1, a: 1 })
152
-
153
- figma.closePlugin(JSON.stringify({
154
- collectionId: collection.id,
155
- lightModeId,
156
- darkModeId,
157
- bgVarId: bgVar.id,
158
- textVarId: textVar.id
159
- }))
160
- } catch (e) {
161
- figma.closePluginWithFailure(e.toString())
162
- }
163
- })()
164
- ```
165
-
166
- ## Bind Color Variable to a Fill
167
-
168
- ```js
169
- (async () => {
170
- try {
171
- const variable = figma.variables.getVariableById("VariableID:1:2")
172
- const rect = figma.createRectangle()
173
- const basePaint = { type: 'SOLID', color: { r: 0, g: 0, b: 0 } }
174
-
175
- // setBoundVariableForPaint returns a NEW paint — capture it!
176
- const boundPaint = figma.variables.setBoundVariableForPaint(basePaint, "color", variable)
177
- rect.fills = [boundPaint]
178
-
179
- figma.closePlugin(JSON.stringify({ nodeId: rect.id }))
180
- } catch (e) {
181
- figma.closePluginWithFailure(e.toString())
182
- }
183
- })()
184
- ```
185
-
186
- ## Create Component Variants with Component Properties
187
-
188
- Component properties (TEXT, BOOLEAN, INSTANCE_SWAP) MUST be added inside the per-variant loop, BEFORE `combineAsVariants`. The component set inherits them from its children.
189
-
190
- ```js
191
- (async () => {
192
- try {
193
- await figma.loadFontAsync({ family: "Inter", style: "Regular" })
194
-
195
- // Assume defaultIconComp is an existing icon component (discovered earlier)
196
- const defaultIconComp = figma.getNodeById('ICON_COMPONENT_ID')
197
-
198
- const components = []
199
- const variants = ["primary", "secondary"]
200
-
201
- for (const variant of variants) {
202
- const comp = figma.createComponent()
203
- comp.name = `variant=${variant}`
204
- comp.layoutMode = 'HORIZONTAL'
205
- comp.primaryAxisAlignItems = 'CENTER'
206
- comp.counterAxisAlignItems = 'CENTER'
207
- comp.paddingLeft = 12
208
- comp.paddingRight = 12
209
- comp.paddingTop = 8
210
- comp.paddingBottom = 8
211
- comp.layoutSizingHorizontal = 'HUG'
212
- comp.layoutSizingVertical = 'HUG'
213
- comp.cornerRadius = 6
214
- comp.itemSpacing = 8
215
-
216
- // TEXT property — label
217
- const labelKey = comp.addComponentProperty('Label', 'TEXT', 'Button')
218
- const label = figma.createText()
219
- label.characters = "Button"
220
- label.fontSize = 14
221
- comp.appendChild(label)
222
- label.componentPropertyReferences = { characters: labelKey }
223
-
224
- // BOOLEAN + INSTANCE_SWAP — icon slot
225
- const showIconKey = comp.addComponentProperty('Show Icon', 'BOOLEAN', false)
226
- const iconSlotKey = comp.addComponentProperty('Icon', 'INSTANCE_SWAP', defaultIconComp.id)
227
- const iconInstance = defaultIconComp.createInstance()
228
- comp.insertChild(0, iconInstance) // icon before label
229
- iconInstance.componentPropertyReferences = {
230
- visible: showIconKey,
231
- mainComponent: iconSlotKey
232
- }
233
-
234
- components.push(comp)
235
- }
236
-
237
- const componentSet = figma.combineAsVariants(components, figma.currentPage)
238
- componentSet.name = "Button"
239
-
240
- // Layout variants in a row after combining (they stack at 0,0 by default)
241
- const colW = 140
242
- componentSet.children.forEach((child, i) => {
243
- child.x = i * colW
244
- child.y = 0
245
- })
246
- // Resize from actual child bounds — formula-based sizing is error-prone
247
- let maxX = 0, maxY = 0
248
- for (const c of componentSet.children) {
249
- maxX = Math.max(maxX, c.x + c.width)
250
- maxY = Math.max(maxY, c.y + c.height)
251
- }
252
- componentSet.resizeWithoutConstraints(maxX + 40, maxY + 40)
253
-
254
- figma.closePlugin(JSON.stringify({
255
- componentSetId: componentSet.id,
256
- componentIds: components.map(c => c.id)
257
- }))
258
- } catch (e) {
259
- figma.closePluginWithFailure(e.toString())
260
- }
261
- })()
262
- ```
263
-
264
- ## Import a Component by Key (Team Libraries)
265
-
266
- `importComponentByKeyAsync` and `importComponentSetByKeyAsync` import components from **team libraries** (not the same file you're working in). For components in the current file, use `figma.getNodeByIdAsync()` or `findOne()`/`findAll()` to locate them directly.
267
-
268
- ```js
269
- (async () => {
270
- try {
271
- // Import a single published component by key
272
- const comp = await figma.importComponentByKeyAsync("COMPONENT_KEY")
273
- const instance = comp.createInstance()
274
- instance.x = 40
275
- instance.y = 40
276
- figma.currentPage.appendChild(instance)
277
-
278
- // Import a published component set by key and select a variant
279
- const compSet = await figma.importComponentSetByKeyAsync("COMPONENT_SET_KEY")
280
- const variant =
281
- compSet.children.find((c) =>
282
- c.type === "COMPONENT" && c.name.includes("size=md")
283
- ) || compSet.defaultVariant
284
-
285
- const variantInstance = variant.createInstance()
286
- variantInstance.x = 240
287
- variantInstance.y = 40
288
- figma.currentPage.appendChild(variantInstance)
289
-
290
- figma.closePlugin(JSON.stringify({
291
- componentId: comp.id,
292
- componentSetId: compSet.id,
293
- placedInstanceIds: [instance.id, variantInstance.id]
294
- }))
295
- } catch (e) {
296
- figma.closePluginWithFailure(e.toString())
297
- }
298
- })()
299
- ```
300
-
301
- ## Component Set with Variable Modes (Full Pattern)
302
-
303
- ```js
304
- (async () => {
305
- try {
306
- await figma.loadFontAsync({ family: "Inter", style: "Medium" })
307
-
308
- // 1. Create color collection with modes per variant
309
- const colors = figma.variables.createVariableCollection("Component/Colors")
310
- colors.renameMode(colors.modes[0].modeId, "primary")
311
- const primaryMode = colors.modes[0].modeId
312
- const secondaryMode = colors.addMode("secondary")
313
-
314
- const bgVar = figma.variables.createVariable("bg", colors, "COLOR")
315
- bgVar.setValueForMode(primaryMode, { r: 0, g: 0.4, b: 0.9, a: 1 })
316
- bgVar.setValueForMode(secondaryMode, { r: 0, g: 0, b: 0, a: 0 })
317
-
318
- const textVar = figma.variables.createVariable("text-color", colors, "COLOR")
319
- textVar.setValueForMode(primaryMode, { r: 1, g: 1, b: 1, a: 1 })
320
- textVar.setValueForMode(secondaryMode, { r: 0.1, g: 0.1, b: 0.1, a: 1 })
321
-
322
- // 2. Create components with variable bindings
323
- const modeMap = { primary: primaryMode, secondary: secondaryMode }
324
- const components = []
325
-
326
- for (const [variantName, modeId] of Object.entries(modeMap)) {
327
- const comp = figma.createComponent()
328
- comp.name = "variant=" + variantName
329
- comp.layoutMode = "HORIZONTAL"
330
- comp.primaryAxisAlignItems = "CENTER"
331
- comp.counterAxisAlignItems = "CENTER"
332
- comp.paddingLeft = 12; comp.paddingRight = 12
333
- comp.layoutSizingHorizontal = "HUG"
334
- comp.layoutSizingVertical = "HUG"
335
- comp.cornerRadius = 6
336
-
337
- // Bind background fill to variable
338
- const bgPaint = figma.variables.setBoundVariableForPaint(
339
- { type: "SOLID", color: { r: 0, g: 0, b: 0 } }, "color", bgVar
340
- )
341
- comp.fills = [bgPaint]
342
-
343
- // Add text with bound color
344
- const label = figma.createText()
345
- label.fontName = { family: "Inter", style: "Medium" }
346
- label.characters = "Button"
347
- label.fontSize = 14
348
- const textPaint = figma.variables.setBoundVariableForPaint(
349
- { type: "SOLID", color: { r: 0, g: 0, b: 0 } }, "color", textVar
350
- )
351
- label.fills = [textPaint]
352
- comp.appendChild(label)
353
-
354
- // 3. CRITICAL: Set explicit mode so this variant renders correctly
355
- comp.setExplicitVariableModeForCollection(colors.id, modeId)
356
-
357
- components.push(comp)
358
- }
359
-
360
- // 4. Combine into component set
361
- const componentSet = figma.combineAsVariants(components, figma.currentPage)
362
- componentSet.name = "Button"
363
-
364
- figma.closePlugin(JSON.stringify({
365
- componentSetId: componentSet.id,
366
- colorCollectionId: colors.id
367
- }))
368
- } catch (e) {
369
- figma.closePluginWithFailure(e.toString())
370
- }
371
- })()
372
- ```
373
-
374
- ## Large ComponentSet with Variable Modes (Multi-Step Pattern)
375
-
376
- For component sets with many variants (50+), split into multiple `use_figma` calls:
377
-
378
- **Call 1: Create variable collections and return IDs**
379
-
380
- ```js
381
- (async () => {
382
- try {
383
- // Hex-to-0-1 helper
384
- const hex = (h) => {
385
- if (!h) return { r: 0, g: 0, b: 0, a: 0 }; // transparent
386
- return {
387
- r: parseInt(h.slice(1,3), 16) / 255,
388
- g: parseInt(h.slice(3,5), 16) / 255,
389
- b: parseInt(h.slice(5,7), 16) / 255,
390
- a: 1
391
- };
392
- };
393
-
394
- const coll = figma.variables.createVariableCollection("MyComponent/Colors");
395
- coll.renameMode(coll.modes[0].modeId, "mode1");
396
- const mode2Id = coll.addMode("mode2");
397
-
398
- // Create variables from data map
399
- const colorData = { "bg/default": ["#0B6BCB", "#636B74"], /* ... */ };
400
- const modeOrder = ["mode1", "mode2"];
401
- const modeIds = { mode1: coll.modes[0].modeId, mode2: mode2Id };
402
- const varIds = {};
403
-
404
- for (const [name, values] of Object.entries(colorData)) {
405
- const v = figma.variables.createVariable(name, coll, "COLOR");
406
- values.forEach((hex_val, i) => {
407
- v.setValueForMode(modeIds[modeOrder[i]], hex_val ? hex(hex_val) : { r:0, g:0, b:0, a:0 });
408
- });
409
- varIds[name] = v.id;
410
- }
411
-
412
- // Return ALL IDs — needed by subsequent calls
413
- figma.closePlugin(JSON.stringify({ collId: coll.id, modeIds, varIds }));
414
- } catch (e) {
415
- figma.closePluginWithFailure(e.toString());
416
- }
417
- })()
418
- ```
419
-
420
- **Call 2: Create components using stored IDs, combine and layout**
421
-
422
- ```js
423
- (async () => {
424
- try {
425
- await figma.loadFontAsync({ family: "Inter", style: "Semi Bold" });
426
-
427
- // Paste IDs from Call 1 as literals
428
- const collId = "VariableCollectionId:X:Y";
429
- const modeIds = { mode1: "X:0", mode2: "X:1" };
430
- const varIds = { /* ... from Call 1 ... */ };
431
-
432
- const getVar = (id) => figma.variables.getVariableById(id);
433
- const bindColor = (varId) => figma.variables.setBoundVariableForPaint(
434
- { type: 'SOLID', color: { r: 0, g: 0, b: 0 } }, 'color', getVar(varId)
435
- );
436
-
437
- const components = [];
438
- for (const mode of ["mode1", "mode2"]) {
439
- for (const state of ["default", "hover"]) {
440
- const comp = figma.createComponent();
441
- comp.name = `mode=${mode}, state=${state}`;
442
- comp.layoutMode = 'HORIZONTAL';
443
- comp.primaryAxisAlignItems = 'CENTER';
444
- comp.counterAxisAlignItems = 'CENTER';
445
- comp.layoutSizingHorizontal = 'HUG';
446
- comp.layoutSizingVertical = 'HUG';
447
- comp.fills = [bindColor(varIds[`bg/${state}`])];
448
- comp.setExplicitVariableModeForCollection(collId, modeIds[mode]);
449
- // ... add text children ...
450
- components.push(comp);
451
- }
452
- }
453
-
454
- // Combine — all children stack at (0,0)!
455
- const cs = figma.combineAsVariants(components, figma.currentPage);
456
- cs.name = "MyComponent";
457
-
458
- // CRITICAL: layout variants in a structured grid mapped to variant axes.
459
- const stateOrder = ["default", "hover"];
460
- const modeOrder2 = ["mode1", "mode2"];
461
- const colW = 140, rowH = 56;
462
-
463
- for (const child of cs.children) {
464
- const props = Object.fromEntries(
465
- child.name.split(', ').map(p => p.split('='))
466
- );
467
- const col = stateOrder.indexOf(props.state);
468
- const row = modeOrder2.indexOf(props.mode);
469
- child.x = col * colW;
470
- child.y = row * rowH;
471
- }
472
- // Resize from actual child bounds
473
- let maxX = 0, maxY = 0;
474
- for (const child of cs.children) {
475
- maxX = Math.max(maxX, child.x + child.width);
476
- maxY = Math.max(maxY, child.y + child.height);
477
- }
478
- cs.resizeWithoutConstraints(maxX + 40, maxY + 40);
479
-
480
- // Wrap in section
481
- const section = figma.createSection();
482
- section.name = "MyComponent Section";
483
- section.appendChild(cs);
484
- section.resizeWithoutConstraints(cs.width + 200, cs.height + 200);
485
-
486
- figma.closePlugin(JSON.stringify({ csId: cs.id, count: components.length }));
487
- } catch (e) {
488
- figma.closePluginWithFailure(e.toString());
489
- }
490
- })()
491
- ```
492
-
493
- ## Read Existing Nodes and Return Data
494
-
495
- ```js
496
- (async () => {
497
- try {
498
- const page = figma.currentPage
499
- const nodes = page.findAll(n => n.type === 'FRAME')
500
- const data = nodes.map(n => ({
501
- id: n.id,
502
- name: n.name,
503
- width: n.width,
504
- height: n.height,
505
- childCount: n.children?.length || 0
506
- }))
507
- figma.closePlugin(JSON.stringify({ frames: data }))
508
- } catch (e) {
509
- figma.closePluginWithFailure(e.toString())
510
- }
511
- })()
512
- ```
1
+ # Common Patterns
2
+
3
+ > Part of the [use_figma skill](../SKILL.md). Working code examples for frequently used operations.
4
+
5
+ ## Contents
6
+
7
+ - Basic Script Structure
8
+ - Create a Styled Shape
9
+ - Create a Text Node
10
+ - Create Frame with Auto-Layout
11
+ - Create Variable Collections and Bindings
12
+ - Create Components and Import by Key
13
+ - Component Sets with Variable Modes
14
+ - Multi-Step Large ComponentSet Pattern
15
+ - Read Existing Nodes and Return Data
16
+
17
+
18
+ ## Basic Script Structure
19
+
20
+ ```js
21
+ (async () => {
22
+ try {
23
+ const createdNodeIds = []
24
+ const mutatedNodeIds = []
25
+
26
+ // Your code here — track every node you create or mutate
27
+ // createdNodeIds.push(newNode.id)
28
+ // mutatedNodeIds.push(existingNode.id)
29
+
30
+ figma.closePlugin(JSON.stringify({
31
+ success: true,
32
+ createdNodeIds,
33
+ mutatedNodeIds,
34
+ // Plus any other useful data for subsequent calls
35
+ count: createdNodeIds.length
36
+ }))
37
+ } catch (e) {
38
+ figma.closePluginWithFailure(e.toString())
39
+ }
40
+ })()
41
+ ```
42
+
43
+ ## Create a Styled Shape
44
+
45
+ ```js
46
+ (async () => {
47
+ try {
48
+ // Find clear space to the right of existing content
49
+ const page = figma.currentPage
50
+ let maxX = 0
51
+ for (const child of page.children) {
52
+ maxX = Math.max(maxX, child.x + child.width)
53
+ }
54
+
55
+ const rect = figma.createRectangle()
56
+ rect.name = "Blue Box"
57
+ rect.resize(200, 100)
58
+ rect.fills = [{ type: 'SOLID', color: { r: 0.047, g: 0.549, b: 0.914 } }]
59
+ rect.cornerRadius = 8
60
+ rect.x = maxX + 100 // offset from existing content
61
+ rect.y = 0
62
+ figma.currentPage.appendChild(rect)
63
+ figma.closePlugin(JSON.stringify({ nodeId: rect.id }))
64
+ } catch (e) {
65
+ figma.closePluginWithFailure(e.toString())
66
+ }
67
+ })()
68
+ ```
69
+
70
+ ## Create a Text Node
71
+
72
+ ```js
73
+ (async () => {
74
+ try {
75
+ // Find clear space to the right of existing content
76
+ const page = figma.currentPage
77
+ let maxX = 0
78
+ for (const child of page.children) {
79
+ maxX = Math.max(maxX, child.x + child.width)
80
+ }
81
+
82
+ await figma.loadFontAsync({ family: "Inter", style: "Regular" })
83
+ const text = figma.createText()
84
+ text.characters = "Hello World"
85
+ text.fontSize = 16
86
+ text.fills = [{ type: 'SOLID', color: { r: 0, g: 0, b: 0 } }]
87
+ text.textAutoResize = 'WIDTH_AND_HEIGHT'
88
+ text.x = maxX + 100
89
+ text.y = 0
90
+ figma.currentPage.appendChild(text)
91
+ figma.closePlugin(JSON.stringify({ nodeId: text.id }))
92
+ } catch (e) {
93
+ figma.closePluginWithFailure(e.toString())
94
+ }
95
+ })()
96
+ ```
97
+
98
+ ## Create Frame with Auto-Layout
99
+
100
+ ```js
101
+ (async () => {
102
+ try {
103
+ // Find clear space to the right of existing content
104
+ const page = figma.currentPage
105
+ let maxX = 0
106
+ for (const child of page.children) {
107
+ maxX = Math.max(maxX, child.x + child.width)
108
+ }
109
+
110
+ const frame = figma.createFrame()
111
+ frame.name = "Card"
112
+ frame.layoutMode = 'VERTICAL'
113
+ frame.primaryAxisAlignItems = 'MIN'
114
+ frame.counterAxisAlignItems = 'MIN'
115
+ frame.paddingLeft = 16
116
+ frame.paddingRight = 16
117
+ frame.paddingTop = 12
118
+ frame.paddingBottom = 12
119
+ frame.itemSpacing = 8
120
+ frame.layoutSizingHorizontal = 'HUG'
121
+ frame.layoutSizingVertical = 'HUG'
122
+ frame.fills = [{ type: 'SOLID', color: { r: 1, g: 1, b: 1 } }]
123
+ frame.cornerRadius = 8
124
+ frame.x = maxX + 100
125
+ frame.y = 0
126
+ figma.currentPage.appendChild(frame)
127
+ figma.closePlugin(JSON.stringify({ nodeId: frame.id }))
128
+ } catch (e) {
129
+ figma.closePluginWithFailure(e.toString())
130
+ }
131
+ })()
132
+ ```
133
+
134
+ ## Create Variable Collection with Multiple Modes
135
+
136
+ ```js
137
+ (async () => {
138
+ try {
139
+ const collection = figma.variables.createVariableCollection("Theme/Colors")
140
+ // Rename the default mode
141
+ collection.renameMode(collection.modes[0].modeId, "Light")
142
+ const darkModeId = collection.addMode("Dark")
143
+ const lightModeId = collection.modes[0].modeId
144
+
145
+ const bgVar = figma.variables.createVariable("bg", collection, "COLOR")
146
+ bgVar.setValueForMode(lightModeId, { r: 1, g: 1, b: 1, a: 1 })
147
+ bgVar.setValueForMode(darkModeId, { r: 0.1, g: 0.1, b: 0.1, a: 1 })
148
+
149
+ const textVar = figma.variables.createVariable("text", collection, "COLOR")
150
+ textVar.setValueForMode(lightModeId, { r: 0, g: 0, b: 0, a: 1 })
151
+ textVar.setValueForMode(darkModeId, { r: 1, g: 1, b: 1, a: 1 })
152
+
153
+ figma.closePlugin(JSON.stringify({
154
+ collectionId: collection.id,
155
+ lightModeId,
156
+ darkModeId,
157
+ bgVarId: bgVar.id,
158
+ textVarId: textVar.id
159
+ }))
160
+ } catch (e) {
161
+ figma.closePluginWithFailure(e.toString())
162
+ }
163
+ })()
164
+ ```
165
+
166
+ ## Bind Color Variable to a Fill
167
+
168
+ ```js
169
+ (async () => {
170
+ try {
171
+ const variable = figma.variables.getVariableById("VariableID:1:2")
172
+ const rect = figma.createRectangle()
173
+ const basePaint = { type: 'SOLID', color: { r: 0, g: 0, b: 0 } }
174
+
175
+ // setBoundVariableForPaint returns a NEW paint — capture it!
176
+ const boundPaint = figma.variables.setBoundVariableForPaint(basePaint, "color", variable)
177
+ rect.fills = [boundPaint]
178
+
179
+ figma.closePlugin(JSON.stringify({ nodeId: rect.id }))
180
+ } catch (e) {
181
+ figma.closePluginWithFailure(e.toString())
182
+ }
183
+ })()
184
+ ```
185
+
186
+ ## Create Component Variants with Component Properties
187
+
188
+ Component properties (TEXT, BOOLEAN, INSTANCE_SWAP) MUST be added inside the per-variant loop, BEFORE `combineAsVariants`. The component set inherits them from its children.
189
+
190
+ ```js
191
+ (async () => {
192
+ try {
193
+ await figma.loadFontAsync({ family: "Inter", style: "Regular" })
194
+
195
+ // Assume defaultIconComp is an existing icon component (discovered earlier)
196
+ const defaultIconComp = figma.getNodeById('ICON_COMPONENT_ID')
197
+
198
+ const components = []
199
+ const variants = ["primary", "secondary"]
200
+
201
+ for (const variant of variants) {
202
+ const comp = figma.createComponent()
203
+ comp.name = `variant=${variant}`
204
+ comp.layoutMode = 'HORIZONTAL'
205
+ comp.primaryAxisAlignItems = 'CENTER'
206
+ comp.counterAxisAlignItems = 'CENTER'
207
+ comp.paddingLeft = 12
208
+ comp.paddingRight = 12
209
+ comp.paddingTop = 8
210
+ comp.paddingBottom = 8
211
+ comp.layoutSizingHorizontal = 'HUG'
212
+ comp.layoutSizingVertical = 'HUG'
213
+ comp.cornerRadius = 6
214
+ comp.itemSpacing = 8
215
+
216
+ // TEXT property — label
217
+ const labelKey = comp.addComponentProperty('Label', 'TEXT', 'Button')
218
+ const label = figma.createText()
219
+ label.characters = "Button"
220
+ label.fontSize = 14
221
+ comp.appendChild(label)
222
+ label.componentPropertyReferences = { characters: labelKey }
223
+
224
+ // BOOLEAN + INSTANCE_SWAP — icon slot
225
+ const showIconKey = comp.addComponentProperty('Show Icon', 'BOOLEAN', false)
226
+ const iconSlotKey = comp.addComponentProperty('Icon', 'INSTANCE_SWAP', defaultIconComp.id)
227
+ const iconInstance = defaultIconComp.createInstance()
228
+ comp.insertChild(0, iconInstance) // icon before label
229
+ iconInstance.componentPropertyReferences = {
230
+ visible: showIconKey,
231
+ mainComponent: iconSlotKey
232
+ }
233
+
234
+ components.push(comp)
235
+ }
236
+
237
+ const componentSet = figma.combineAsVariants(components, figma.currentPage)
238
+ componentSet.name = "Button"
239
+
240
+ // Layout variants in a row after combining (they stack at 0,0 by default)
241
+ const colW = 140
242
+ componentSet.children.forEach((child, i) => {
243
+ child.x = i * colW
244
+ child.y = 0
245
+ })
246
+ // Resize from actual child bounds — formula-based sizing is error-prone
247
+ let maxX = 0, maxY = 0
248
+ for (const c of componentSet.children) {
249
+ maxX = Math.max(maxX, c.x + c.width)
250
+ maxY = Math.max(maxY, c.y + c.height)
251
+ }
252
+ componentSet.resizeWithoutConstraints(maxX + 40, maxY + 40)
253
+
254
+ figma.closePlugin(JSON.stringify({
255
+ componentSetId: componentSet.id,
256
+ componentIds: components.map(c => c.id)
257
+ }))
258
+ } catch (e) {
259
+ figma.closePluginWithFailure(e.toString())
260
+ }
261
+ })()
262
+ ```
263
+
264
+ ## Import a Component by Key (Team Libraries)
265
+
266
+ `importComponentByKeyAsync` and `importComponentSetByKeyAsync` import components from **team libraries** (not the same file you're working in). For components in the current file, use `figma.getNodeByIdAsync()` or `findOne()`/`findAll()` to locate them directly.
267
+
268
+ ```js
269
+ (async () => {
270
+ try {
271
+ // Import a single published component by key
272
+ const comp = await figma.importComponentByKeyAsync("COMPONENT_KEY")
273
+ const instance = comp.createInstance()
274
+ instance.x = 40
275
+ instance.y = 40
276
+ figma.currentPage.appendChild(instance)
277
+
278
+ // Import a published component set by key and select a variant
279
+ const compSet = await figma.importComponentSetByKeyAsync("COMPONENT_SET_KEY")
280
+ const variant =
281
+ compSet.children.find((c) =>
282
+ c.type === "COMPONENT" && c.name.includes("size=md")
283
+ ) || compSet.defaultVariant
284
+
285
+ const variantInstance = variant.createInstance()
286
+ variantInstance.x = 240
287
+ variantInstance.y = 40
288
+ figma.currentPage.appendChild(variantInstance)
289
+
290
+ figma.closePlugin(JSON.stringify({
291
+ componentId: comp.id,
292
+ componentSetId: compSet.id,
293
+ placedInstanceIds: [instance.id, variantInstance.id]
294
+ }))
295
+ } catch (e) {
296
+ figma.closePluginWithFailure(e.toString())
297
+ }
298
+ })()
299
+ ```
300
+
301
+ ## Component Set with Variable Modes (Full Pattern)
302
+
303
+ ```js
304
+ (async () => {
305
+ try {
306
+ await figma.loadFontAsync({ family: "Inter", style: "Medium" })
307
+
308
+ // 1. Create color collection with modes per variant
309
+ const colors = figma.variables.createVariableCollection("Component/Colors")
310
+ colors.renameMode(colors.modes[0].modeId, "primary")
311
+ const primaryMode = colors.modes[0].modeId
312
+ const secondaryMode = colors.addMode("secondary")
313
+
314
+ const bgVar = figma.variables.createVariable("bg", colors, "COLOR")
315
+ bgVar.setValueForMode(primaryMode, { r: 0, g: 0.4, b: 0.9, a: 1 })
316
+ bgVar.setValueForMode(secondaryMode, { r: 0, g: 0, b: 0, a: 0 })
317
+
318
+ const textVar = figma.variables.createVariable("text-color", colors, "COLOR")
319
+ textVar.setValueForMode(primaryMode, { r: 1, g: 1, b: 1, a: 1 })
320
+ textVar.setValueForMode(secondaryMode, { r: 0.1, g: 0.1, b: 0.1, a: 1 })
321
+
322
+ // 2. Create components with variable bindings
323
+ const modeMap = { primary: primaryMode, secondary: secondaryMode }
324
+ const components = []
325
+
326
+ for (const [variantName, modeId] of Object.entries(modeMap)) {
327
+ const comp = figma.createComponent()
328
+ comp.name = "variant=" + variantName
329
+ comp.layoutMode = "HORIZONTAL"
330
+ comp.primaryAxisAlignItems = "CENTER"
331
+ comp.counterAxisAlignItems = "CENTER"
332
+ comp.paddingLeft = 12; comp.paddingRight = 12
333
+ comp.layoutSizingHorizontal = "HUG"
334
+ comp.layoutSizingVertical = "HUG"
335
+ comp.cornerRadius = 6
336
+
337
+ // Bind background fill to variable
338
+ const bgPaint = figma.variables.setBoundVariableForPaint(
339
+ { type: "SOLID", color: { r: 0, g: 0, b: 0 } }, "color", bgVar
340
+ )
341
+ comp.fills = [bgPaint]
342
+
343
+ // Add text with bound color
344
+ const label = figma.createText()
345
+ label.fontName = { family: "Inter", style: "Medium" }
346
+ label.characters = "Button"
347
+ label.fontSize = 14
348
+ const textPaint = figma.variables.setBoundVariableForPaint(
349
+ { type: "SOLID", color: { r: 0, g: 0, b: 0 } }, "color", textVar
350
+ )
351
+ label.fills = [textPaint]
352
+ comp.appendChild(label)
353
+
354
+ // 3. CRITICAL: Set explicit mode so this variant renders correctly
355
+ comp.setExplicitVariableModeForCollection(colors.id, modeId)
356
+
357
+ components.push(comp)
358
+ }
359
+
360
+ // 4. Combine into component set
361
+ const componentSet = figma.combineAsVariants(components, figma.currentPage)
362
+ componentSet.name = "Button"
363
+
364
+ figma.closePlugin(JSON.stringify({
365
+ componentSetId: componentSet.id,
366
+ colorCollectionId: colors.id
367
+ }))
368
+ } catch (e) {
369
+ figma.closePluginWithFailure(e.toString())
370
+ }
371
+ })()
372
+ ```
373
+
374
+ ## Large ComponentSet with Variable Modes (Multi-Step Pattern)
375
+
376
+ For component sets with many variants (50+), split into multiple `use_figma` calls:
377
+
378
+ **Call 1: Create variable collections and return IDs**
379
+
380
+ ```js
381
+ (async () => {
382
+ try {
383
+ // Hex-to-0-1 helper
384
+ const hex = (h) => {
385
+ if (!h) return { r: 0, g: 0, b: 0, a: 0 }; // transparent
386
+ return {
387
+ r: parseInt(h.slice(1,3), 16) / 255,
388
+ g: parseInt(h.slice(3,5), 16) / 255,
389
+ b: parseInt(h.slice(5,7), 16) / 255,
390
+ a: 1
391
+ };
392
+ };
393
+
394
+ const coll = figma.variables.createVariableCollection("MyComponent/Colors");
395
+ coll.renameMode(coll.modes[0].modeId, "mode1");
396
+ const mode2Id = coll.addMode("mode2");
397
+
398
+ // Create variables from data map
399
+ const colorData = { "bg/default": ["#0B6BCB", "#636B74"], /* ... */ };
400
+ const modeOrder = ["mode1", "mode2"];
401
+ const modeIds = { mode1: coll.modes[0].modeId, mode2: mode2Id };
402
+ const varIds = {};
403
+
404
+ for (const [name, values] of Object.entries(colorData)) {
405
+ const v = figma.variables.createVariable(name, coll, "COLOR");
406
+ values.forEach((hex_val, i) => {
407
+ v.setValueForMode(modeIds[modeOrder[i]], hex_val ? hex(hex_val) : { r:0, g:0, b:0, a:0 });
408
+ });
409
+ varIds[name] = v.id;
410
+ }
411
+
412
+ // Return ALL IDs — needed by subsequent calls
413
+ figma.closePlugin(JSON.stringify({ collId: coll.id, modeIds, varIds }));
414
+ } catch (e) {
415
+ figma.closePluginWithFailure(e.toString());
416
+ }
417
+ })()
418
+ ```
419
+
420
+ **Call 2: Create components using stored IDs, combine and layout**
421
+
422
+ ```js
423
+ (async () => {
424
+ try {
425
+ await figma.loadFontAsync({ family: "Inter", style: "Semi Bold" });
426
+
427
+ // Paste IDs from Call 1 as literals
428
+ const collId = "VariableCollectionId:X:Y";
429
+ const modeIds = { mode1: "X:0", mode2: "X:1" };
430
+ const varIds = { /* ... from Call 1 ... */ };
431
+
432
+ const getVar = (id) => figma.variables.getVariableById(id);
433
+ const bindColor = (varId) => figma.variables.setBoundVariableForPaint(
434
+ { type: 'SOLID', color: { r: 0, g: 0, b: 0 } }, 'color', getVar(varId)
435
+ );
436
+
437
+ const components = [];
438
+ for (const mode of ["mode1", "mode2"]) {
439
+ for (const state of ["default", "hover"]) {
440
+ const comp = figma.createComponent();
441
+ comp.name = `mode=${mode}, state=${state}`;
442
+ comp.layoutMode = 'HORIZONTAL';
443
+ comp.primaryAxisAlignItems = 'CENTER';
444
+ comp.counterAxisAlignItems = 'CENTER';
445
+ comp.layoutSizingHorizontal = 'HUG';
446
+ comp.layoutSizingVertical = 'HUG';
447
+ comp.fills = [bindColor(varIds[`bg/${state}`])];
448
+ comp.setExplicitVariableModeForCollection(collId, modeIds[mode]);
449
+ // ... add text children ...
450
+ components.push(comp);
451
+ }
452
+ }
453
+
454
+ // Combine — all children stack at (0,0)!
455
+ const cs = figma.combineAsVariants(components, figma.currentPage);
456
+ cs.name = "MyComponent";
457
+
458
+ // CRITICAL: layout variants in a structured grid mapped to variant axes.
459
+ const stateOrder = ["default", "hover"];
460
+ const modeOrder2 = ["mode1", "mode2"];
461
+ const colW = 140, rowH = 56;
462
+
463
+ for (const child of cs.children) {
464
+ const props = Object.fromEntries(
465
+ child.name.split(', ').map(p => p.split('='))
466
+ );
467
+ const col = stateOrder.indexOf(props.state);
468
+ const row = modeOrder2.indexOf(props.mode);
469
+ child.x = col * colW;
470
+ child.y = row * rowH;
471
+ }
472
+ // Resize from actual child bounds
473
+ let maxX = 0, maxY = 0;
474
+ for (const child of cs.children) {
475
+ maxX = Math.max(maxX, child.x + child.width);
476
+ maxY = Math.max(maxY, child.y + child.height);
477
+ }
478
+ cs.resizeWithoutConstraints(maxX + 40, maxY + 40);
479
+
480
+ // Wrap in section
481
+ const section = figma.createSection();
482
+ section.name = "MyComponent Section";
483
+ section.appendChild(cs);
484
+ section.resizeWithoutConstraints(cs.width + 200, cs.height + 200);
485
+
486
+ figma.closePlugin(JSON.stringify({ csId: cs.id, count: components.length }));
487
+ } catch (e) {
488
+ figma.closePluginWithFailure(e.toString());
489
+ }
490
+ })()
491
+ ```
492
+
493
+ ## Read Existing Nodes and Return Data
494
+
495
+ ```js
496
+ (async () => {
497
+ try {
498
+ const page = figma.currentPage
499
+ const nodes = page.findAll(n => n.type === 'FRAME')
500
+ const data = nodes.map(n => ({
501
+ id: n.id,
502
+ name: n.name,
503
+ width: n.width,
504
+ height: n.height,
505
+ childCount: n.children?.length || 0
506
+ }))
507
+ figma.closePlugin(JSON.stringify({ frames: data }))
508
+ } catch (e) {
509
+ figma.closePluginWithFailure(e.toString())
510
+ }
511
+ })()
512
+ ```