@sarjallab09/figma-intelligence 1.0.0
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.
- package/LICENSE +26 -0
- package/README.md +327 -0
- package/bin/cli.js +859 -0
- package/design-bridge/.env.example +5 -0
- package/design-bridge/bridge.js +196 -0
- package/design-bridge/lib/assets.js +367 -0
- package/design-bridge/lib/prompt.js +85 -0
- package/design-bridge/lib/server.js +66 -0
- package/design-bridge/lib/stitch.js +37 -0
- package/design-bridge/lib/tokens.js +82 -0
- package/design-bridge/package-lock.json +579 -0
- package/design-bridge/package.json +19 -0
- package/figma-bridge-plugin/README.md +97 -0
- package/figma-bridge-plugin/anthropic-chat-runner.js +192 -0
- package/figma-bridge-plugin/bridge-relay.js +2363 -0
- package/figma-bridge-plugin/chat-runner.js +459 -0
- package/figma-bridge-plugin/code.js +1528 -0
- package/figma-bridge-plugin/codex-runner.js +505 -0
- package/figma-bridge-plugin/component-schemas.js +110 -0
- package/figma-bridge-plugin/content-context.js +869 -0
- package/figma-bridge-plugin/create-button.js +216 -0
- package/figma-bridge-plugin/gemini-cli-runner.js +291 -0
- package/figma-bridge-plugin/gemini-runner.js +187 -0
- package/figma-bridge-plugin/html-to-figma.js +927 -0
- package/figma-bridge-plugin/knowledge-hub/.gitkeep +0 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/anatomy-spec.md +159 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/api-spec.md +162 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/color-spec.md +148 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/full-spec-template.md +314 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/property-spec.md +175 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/screen-reader-spec.md +180 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/structure-spec.md +165 -0
- package/figma-bridge-plugin/manifest.json +21 -0
- package/figma-bridge-plugin/package-lock.json +1936 -0
- package/figma-bridge-plugin/package.json +20 -0
- package/figma-bridge-plugin/perplexity-runner.js +188 -0
- package/figma-bridge-plugin/references/SKILL.md +178 -0
- package/figma-bridge-plugin/references/anatomy-spec.md +159 -0
- package/figma-bridge-plugin/references/api-spec.md +162 -0
- package/figma-bridge-plugin/references/color-spec.md +148 -0
- package/figma-bridge-plugin/references/full-spec-template.md +314 -0
- package/figma-bridge-plugin/references/property-spec.md +175 -0
- package/figma-bridge-plugin/references/screen-reader-spec.md +180 -0
- package/figma-bridge-plugin/references/structure-spec.md +165 -0
- package/figma-bridge-plugin/shared-prompt-config.js +604 -0
- package/figma-bridge-plugin/spec-helpers/build-table.js +269 -0
- package/figma-bridge-plugin/spec-helpers/classify-elements.js +189 -0
- package/figma-bridge-plugin/spec-helpers/index.js +35 -0
- package/figma-bridge-plugin/spec-helpers/parse-figma-link.js +49 -0
- package/figma-bridge-plugin/spec-helpers/position-markers.js +158 -0
- package/figma-bridge-plugin/stitch-auth.js +322 -0
- package/figma-bridge-plugin/stitch-runner.js +1427 -0
- package/figma-bridge-plugin/token-resolver.js +107 -0
- package/figma-bridge-plugin/ui.html +4467 -0
- package/figma-intelligence-layer/.env.example +39 -0
- package/figma-intelligence-layer/docs/local-image-generation.md +60 -0
- package/figma-intelligence-layer/examples/comfyui-workflow-template.example.json +101 -0
- package/figma-intelligence-layer/jest.config.js +14 -0
- package/figma-intelligence-layer/mcp-config.json +19 -0
- package/figma-intelligence-layer/package-lock.json +5892 -0
- package/figma-intelligence-layer/package.json +48 -0
- package/figma-intelligence-layer/scripts/setup-comfyui-local.sh +67 -0
- package/figma-intelligence-layer/scripts/start-comfyui.sh +33 -0
- package/figma-intelligence-layer/src/index.ts +2233 -0
- package/figma-intelligence-layer/src/shared/auto-layout-validator.ts +404 -0
- package/figma-intelligence-layer/src/shared/cache.ts +187 -0
- package/figma-intelligence-layer/src/shared/color-operations.ts +533 -0
- package/figma-intelligence-layer/src/shared/color-utils.ts +138 -0
- package/figma-intelligence-layer/src/shared/component-script-builder.ts +413 -0
- package/figma-intelligence-layer/src/shared/component-templates.ts +2767 -0
- package/figma-intelligence-layer/src/shared/concept-taxonomy.ts +694 -0
- package/figma-intelligence-layer/src/shared/decision-log.ts +128 -0
- package/figma-intelligence-layer/src/shared/design-system-context.ts +568 -0
- package/figma-intelligence-layer/src/shared/design-system-intelligence.ts +131 -0
- package/figma-intelligence-layer/src/shared/design-system-matcher.ts +184 -0
- package/figma-intelligence-layer/src/shared/design-system-normalizers.ts +196 -0
- package/figma-intelligence-layer/src/shared/design-system-tokens.ts +295 -0
- package/figma-intelligence-layer/src/shared/dtcg-validator.ts +530 -0
- package/figma-intelligence-layer/src/shared/enrichment-pipeline.ts +671 -0
- package/figma-intelligence-layer/src/shared/figma-bridge.ts +1408 -0
- package/figma-intelligence-layer/src/shared/font-config.ts +126 -0
- package/figma-intelligence-layer/src/shared/icon-catalog.ts +360 -0
- package/figma-intelligence-layer/src/shared/icon-fetch.ts +80 -0
- package/figma-intelligence-layer/src/shared/prototype-script-builder.ts +162 -0
- package/figma-intelligence-layer/src/shared/response-compression.ts +440 -0
- package/figma-intelligence-layer/src/shared/semantic-token-catalog.ts +324 -0
- package/figma-intelligence-layer/src/shared/token-binder.ts +505 -0
- package/figma-intelligence-layer/src/shared/token-math.ts +427 -0
- package/figma-intelligence-layer/src/shared/token-naming.ts +468 -0
- package/figma-intelligence-layer/src/shared/token-utils.ts +420 -0
- package/figma-intelligence-layer/src/shared/types.ts +346 -0
- package/figma-intelligence-layer/src/shared/typography-presets.ts +94 -0
- package/figma-intelligence-layer/src/shared/unsplash.ts +165 -0
- package/figma-intelligence-layer/src/shared/vision-client.ts +607 -0
- package/figma-intelligence-layer/src/shared/vision-provider-anthropic.ts +334 -0
- package/figma-intelligence-layer/src/shared/vision-provider-openai.ts +446 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotate-handler.ts +782 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotate-renderer.ts +496 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotation-kit.ts +230 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/colorblind-sim.ts +66 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/index.ts +810 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-analyzer.ts +1191 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-figma-page.ts +1346 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-handler.ts +148 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/vpat-figma-page.ts +499 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/vpat-report.ts +910 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/wcag-checker.ts +989 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/wcag-criteria.ts +1160 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/design-from-ref/index.ts +424 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/component-recognizer.ts +38 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/ds-matcher.ts +111 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/font-matcher.ts +114 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/icon-resolver.ts +103 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/index.ts +1060 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/layout-segmenter.ts +18 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/token-inferencer.ts +39 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/vision-pipeline.ts +58 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/sketch-to-design/index.ts +298 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/visual-audit/index.ts +197 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/component-audit/index.ts +494 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/intent-translator/index.ts +356 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/layout-intelligence/container-patterns.ts +123 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/layout-intelligence/index.ts +663 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/built-in-rules.yaml +56 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/index.ts +614 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/rule-engine.ts +113 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/theme-generator/color-theory.ts +178 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/theme-generator/index.ts +470 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/variant-expander/index.ts +429 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/variant-expander/token-override-maps.ts +226 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/ai-image-insert/index.ts +535 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/component-archaeologist/index.ts +660 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/component-archaeologist/pattern-fingerprints.ts +209 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/composition-builder/index.ts +540 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/figma-animated-build.ts +391 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/page-architect/index.ts +2019 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/page-architect/screen-templates.ts +131 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/prototype-map/index.ts +381 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/prototype-wire/index.ts +565 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/swarm-build/index.ts +764 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/system-drift/index.ts +535 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/unsplash-search/index.ts +84 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/url-to-frame/index.ts +401 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/css-animations.ts +68 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/framer-motion.ts +78 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/swift-animations.ts +93 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/index.ts +596 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/ci-check/index.ts +462 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/export-tokens/index.ts +1470 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/generate-component-code/index.ts +829 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/handoff-spec/index.ts +702 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/icon-library-sync/index.ts +483 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/sync-from-code/index.ts +501 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/sync-from-code/storybook-parser.ts +106 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/watch-docs/index.ts +676 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/webhook-listener/index.ts +560 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/apg-doc/index.ts +1043 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/component-detection.ts +620 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/anatomy.ts +331 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/color-tokens.ts +77 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/properties.ts +54 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/snapshot.ts +287 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/spacing.ts +71 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/states.ts +43 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/typography.ts +71 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/index.ts +221 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/_default.ts +166 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/accordion.ts +232 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/alert.ts +234 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/avatar-group.ts +270 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/avatar.ts +249 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/badge.ts +231 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/banner.ts +293 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/breadcrumb.ts +240 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/button.ts +243 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/calendar.ts +307 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/card.ts +143 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/checkbox.ts +227 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/chip.ts +233 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/combobox.ts +282 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/datepicker.ts +276 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/divider.ts +223 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/drawer.ts +255 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/dropdown-menu.ts +289 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/empty-state.ts +261 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/file-uploader.ts +290 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/form.ts +265 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/grid.ts +238 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/icon.ts +255 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/index.ts +128 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/inline-edit.ts +286 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/inline-message.ts +255 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/input.ts +330 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/link.ts +247 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/list.ts +250 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/menu.ts +247 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/modal.ts +144 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/navbar.ts +264 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/navigation.ts +251 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/number-input.ts +261 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/pagination.ts +248 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/popover.ts +270 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/progress.ts +251 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/radio.ts +142 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/range-slider.ts +282 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/rating.ts +250 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/search.ts +258 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/segmented-control.ts +265 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/select.ts +319 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/skeleton.ts +256 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/slider.ts +232 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/spinner.ts +239 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/status-dot.ts +252 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/stepper.ts +270 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/table.ts +244 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tabs.ts +143 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tag.ts +243 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/textarea.ts +259 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/time-picker.ts +293 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toast.ts +144 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toggle.ts +289 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toolbar.ts +267 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tooltip.ts +232 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/treeview.ts +257 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/typography.ts +319 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/legacy-compat.ts +121 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/anatomy-diagram.ts +430 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/figma-page.ts +312 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/json.ts +129 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/markdown.ts +78 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/visual-doc.ts +2333 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/accessibility.ts +100 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/anatomy.ts +32 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/color-tokens.ts +59 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/content-guidance.ts +18 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/design-tokens.ts +53 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/interaction-rules.ts +19 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/overview.ts +91 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/properties-api.ts +71 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/qa-criteria.ts +19 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/related-components.ts +110 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/responsive.ts +19 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/size-specs.ts +67 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/spacing-structure.ts +58 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/state-specs.ts +79 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/states.ts +50 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/type-hierarchy.ts +33 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/typography.ts +55 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/usage-guidelines.ts +73 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/variants.ts +81 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/types.ts +409 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/index.ts +198 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/renderer.ts +701 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/types.ts +88 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/decision-log/index.ts +135 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/design-decision-log/index.ts +491 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/ds-primitives/index.ts +416 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/ds-scaffolder/index.ts +722 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/ds-variables/index.ts +449 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/health-report/index.ts +393 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/index.ts +406 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/figma-page.ts +292 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/json.ts +24 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/markdown.ts +172 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/naming-guide.ts +409 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/token-analytics/index.ts +594 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/token-docs/index.ts +710 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/token-migrate/index.ts +458 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/token-naming/index.ts +134 -0
- package/figma-intelligence-layer/tests/apg-doc.test.ts +101 -0
- package/figma-intelligence-layer/tests/design-system-context.test.ts +152 -0
- package/figma-intelligence-layer/tests/design-system-matcher.test.ts +144 -0
- package/figma-intelligence-layer/tests/figma-bridge.test.ts +83 -0
- package/figma-intelligence-layer/tests/generate-image-and-insert.test.ts +56 -0
- package/figma-intelligence-layer/tests/screen-cloner-regression.test.ts +69 -0
- package/figma-intelligence-layer/tests/smoke.test.ts +174 -0
- package/figma-intelligence-layer/tests/spec-generator.test.ts +127 -0
- package/figma-intelligence-layer/tests/token-migrate.test.ts +21 -0
- package/figma-intelligence-layer/tests/token-naming.test.ts +30 -0
- package/figma-intelligence-layer/tsconfig.json +19 -0
- package/package.json +35 -0
- package/scripts/clean-existing-chunks.js +179 -0
- package/scripts/connect-ai-tool.js +490 -0
- package/scripts/convert-hub-pdfs.js +425 -0
- package/scripts/figma-mcp-status.js +349 -0
- package/scripts/register-codex-mcp.js +96 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2
|
+
// Font Configuration System
|
|
3
|
+
// Provides configurable font families for heading, body, mono, and UI roles.
|
|
4
|
+
// All Figma script generators use this instead of hardcoded "Inter" references.
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
export interface FontFamilyConfig {
|
|
8
|
+
family: string;
|
|
9
|
+
styles: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface FontConfig {
|
|
13
|
+
heading: FontFamilyConfig;
|
|
14
|
+
body: FontFamilyConfig;
|
|
15
|
+
mono: FontFamilyConfig;
|
|
16
|
+
ui: FontFamilyConfig;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type FontRole = keyof FontConfig;
|
|
20
|
+
|
|
21
|
+
export const DEFAULT_FONT_CONFIG: FontConfig = {
|
|
22
|
+
heading: { family: "Inter", styles: ["Bold", "SemiBold", "Medium"] },
|
|
23
|
+
body: { family: "Inter", styles: ["Regular", "Medium", "Bold"] },
|
|
24
|
+
mono: { family: "JetBrains Mono", styles: ["Regular", "Medium"] },
|
|
25
|
+
ui: { family: "Inter", styles: ["Regular", "Medium", "SemiBold"] },
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Merge a partial font config with the defaults.
|
|
30
|
+
* When dsId is provided, the design system's font family is used as the
|
|
31
|
+
* default for heading, body, and ui roles (user overrides still win).
|
|
32
|
+
*/
|
|
33
|
+
export function resolveFontConfig(partial?: Partial<FontConfig>, dsId?: string | null): FontConfig {
|
|
34
|
+
let base = { ...DEFAULT_FONT_CONFIG };
|
|
35
|
+
|
|
36
|
+
// When a DS is selected, use its font family as default for all text roles
|
|
37
|
+
if (dsId) {
|
|
38
|
+
const dsFont = _getDSFont(dsId);
|
|
39
|
+
if (dsFont) {
|
|
40
|
+
base = {
|
|
41
|
+
heading: { family: dsFont, styles: DEFAULT_FONT_CONFIG.heading.styles },
|
|
42
|
+
body: { family: dsFont, styles: DEFAULT_FONT_CONFIG.body.styles },
|
|
43
|
+
mono: DEFAULT_FONT_CONFIG.mono, // Mono stays as-is
|
|
44
|
+
ui: { family: dsFont, styles: DEFAULT_FONT_CONFIG.ui.styles },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!partial) return base;
|
|
50
|
+
return {
|
|
51
|
+
heading: partial.heading ?? base.heading,
|
|
52
|
+
body: partial.body ?? base.body,
|
|
53
|
+
mono: partial.mono ?? base.mono,
|
|
54
|
+
ui: partial.ui ?? base.ui,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Lazy-loaded reference to avoid circular import at module load time
|
|
59
|
+
let _getDesignSystemFontFamily: ((dsId: string) => string | null) | null = null;
|
|
60
|
+
function _getDSFont(dsId: string): string | null {
|
|
61
|
+
if (!_getDesignSystemFontFamily) {
|
|
62
|
+
try {
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
64
|
+
_getDesignSystemFontFamily = require("./design-system-tokens.js").getDesignSystemFontFamily;
|
|
65
|
+
} catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return _getDesignSystemFontFamily!(dsId);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Generate all `figma.loadFontAsync()` calls needed for the given config.
|
|
74
|
+
* Includes try/catch fallback to Inter if a custom font is unavailable.
|
|
75
|
+
*/
|
|
76
|
+
export function generateFontLoadScript(config: FontConfig): string {
|
|
77
|
+
const loads: string[] = [];
|
|
78
|
+
const seen = new Set<string>();
|
|
79
|
+
|
|
80
|
+
for (const role of ["heading", "body", "mono", "ui"] as FontRole[]) {
|
|
81
|
+
const { family, styles } = config[role];
|
|
82
|
+
for (const style of styles) {
|
|
83
|
+
const key = `${family}::${style}`;
|
|
84
|
+
if (seen.has(key)) continue;
|
|
85
|
+
seen.add(key);
|
|
86
|
+
|
|
87
|
+
if (family === "Inter") {
|
|
88
|
+
// Inter is always available in Figma
|
|
89
|
+
loads.push(` await figma.loadFontAsync({ family: "Inter", style: ${JSON.stringify(style)} });`);
|
|
90
|
+
} else {
|
|
91
|
+
loads.push(
|
|
92
|
+
` try {`,
|
|
93
|
+
` await figma.loadFontAsync({ family: ${JSON.stringify(family)}, style: ${JSON.stringify(style)} });`,
|
|
94
|
+
` } catch (_) {`,
|
|
95
|
+
` await figma.loadFontAsync({ family: "Inter", style: ${JSON.stringify(style)} });`,
|
|
96
|
+
` }`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return loads.join("\n");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Return a Figma fontName object literal string for use in generated scripts.
|
|
107
|
+
* E.g. `{ family: "Inter", style: "Bold" }`
|
|
108
|
+
*/
|
|
109
|
+
export function fontNameLiteral(role: FontRole, style: string, config: FontConfig): string {
|
|
110
|
+
const family = config[role].family;
|
|
111
|
+
return `{ family: ${JSON.stringify(family)}, style: ${JSON.stringify(style)} }`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Map a weight name to a Figma font style string.
|
|
116
|
+
*/
|
|
117
|
+
export function weightToStyle(weight: string): string {
|
|
118
|
+
const map: Record<string, string> = {
|
|
119
|
+
regular: "Regular",
|
|
120
|
+
medium: "Medium",
|
|
121
|
+
semibold: "SemiBold",
|
|
122
|
+
bold: "Bold",
|
|
123
|
+
light: "Light",
|
|
124
|
+
};
|
|
125
|
+
return map[weight.toLowerCase()] ?? "Regular";
|
|
126
|
+
}
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2
|
+
// Icon Catalog
|
|
3
|
+
// Browseable, categorized icon registry with search, naming taxonomy
|
|
4
|
+
// (icon/{category}/{name}), and custom icon set registration for enterprise.
|
|
5
|
+
// Default catalog ships ~80-100 curated Material Symbols entries with
|
|
6
|
+
// Iconify API fallback for anything not in the catalog.
|
|
7
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
export type IconCategory =
|
|
10
|
+
| "action"
|
|
11
|
+
| "navigation"
|
|
12
|
+
| "content"
|
|
13
|
+
| "communication"
|
|
14
|
+
| "status"
|
|
15
|
+
| "media"
|
|
16
|
+
| "file"
|
|
17
|
+
| "social"
|
|
18
|
+
| "editor"
|
|
19
|
+
| "toggle"
|
|
20
|
+
| "device"
|
|
21
|
+
| "custom";
|
|
22
|
+
|
|
23
|
+
export interface IconEntry {
|
|
24
|
+
/** Canonical name following icon/{category}/{name} taxonomy */
|
|
25
|
+
name: string;
|
|
26
|
+
/** Display name for browsing UI */
|
|
27
|
+
displayName: string;
|
|
28
|
+
/** Category for grouping and filtering */
|
|
29
|
+
category: IconCategory;
|
|
30
|
+
/** Tags for search */
|
|
31
|
+
tags: string[];
|
|
32
|
+
/** Iconify prefix:name identifier for fetching SVG */
|
|
33
|
+
iconifyId: string;
|
|
34
|
+
/** Whether a filled variant exists */
|
|
35
|
+
hasFilled: boolean;
|
|
36
|
+
/** Whether an outlined variant exists */
|
|
37
|
+
hasOutlined: boolean;
|
|
38
|
+
/** Common aliases for fuzzy matching */
|
|
39
|
+
aliases: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CustomIconSet {
|
|
43
|
+
/** Unique prefix for the custom set (e.g., "acme") */
|
|
44
|
+
prefix: string;
|
|
45
|
+
/** Display name */
|
|
46
|
+
name: string;
|
|
47
|
+
/** Description */
|
|
48
|
+
description: string;
|
|
49
|
+
/** Icon entries in this custom set */
|
|
50
|
+
icons: IconEntry[];
|
|
51
|
+
/** Optional Iconify-compatible API endpoint */
|
|
52
|
+
apiEndpoint?: string;
|
|
53
|
+
/** Inline SVG map for offline/bundled icons */
|
|
54
|
+
svgMap?: Record<string, string>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface IconCatalog {
|
|
58
|
+
/** Default icon library prefix for Iconify */
|
|
59
|
+
defaultLibrary: string;
|
|
60
|
+
/** All registered icons */
|
|
61
|
+
entries: IconEntry[];
|
|
62
|
+
/** Custom icon sets registered by enterprise teams */
|
|
63
|
+
customSets: CustomIconSet[];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ─── Helper to define entries concisely ────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
function icon(
|
|
69
|
+
category: IconCategory,
|
|
70
|
+
slug: string,
|
|
71
|
+
displayName: string,
|
|
72
|
+
tags: string[],
|
|
73
|
+
aliases: string[] = [],
|
|
74
|
+
iconifySlug?: string,
|
|
75
|
+
): IconEntry {
|
|
76
|
+
return {
|
|
77
|
+
name: `icon/${category}/${slug}`,
|
|
78
|
+
displayName,
|
|
79
|
+
category,
|
|
80
|
+
tags,
|
|
81
|
+
iconifyId: `material-symbols:${iconifySlug ?? slug}`,
|
|
82
|
+
hasFilled: true,
|
|
83
|
+
hasOutlined: true,
|
|
84
|
+
aliases,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ─── Curated catalog entries ───────────────────────────────────────────────
|
|
89
|
+
|
|
90
|
+
const ACTION_ICONS: IconEntry[] = [
|
|
91
|
+
icon("action", "delete", "Delete", ["remove", "trash", "bin"], ["trash", "bin"]),
|
|
92
|
+
icon("action", "edit", "Edit", ["modify", "pencil", "write"], ["pencil"]),
|
|
93
|
+
icon("action", "save", "Save", ["store", "disk", "floppy"], ["floppy"]),
|
|
94
|
+
icon("action", "copy", "Copy", ["duplicate", "clone"], ["duplicate"]),
|
|
95
|
+
icon("action", "share", "Share", ["send", "distribute"], []),
|
|
96
|
+
icon("action", "download", "Download", ["save", "export", "get"], ["export"]),
|
|
97
|
+
icon("action", "upload", "Upload", ["import", "send"], ["import"]),
|
|
98
|
+
icon("action", "print", "Print", ["paper", "output"], []),
|
|
99
|
+
icon("action", "settings", "Settings", ["gear", "preferences", "config"], ["gear", "cog", "preferences"]),
|
|
100
|
+
icon("action", "search", "Search", ["find", "lookup", "magnify"], ["magnifier", "magnifying-glass", "find"]),
|
|
101
|
+
icon("action", "add", "Add", ["plus", "create", "new"], ["plus", "create"]),
|
|
102
|
+
icon("action", "remove", "Remove", ["minus", "subtract"], ["minus"]),
|
|
103
|
+
icon("action", "done", "Done", ["check", "complete", "tick"], ["check", "checkmark", "tick"]),
|
|
104
|
+
icon("action", "close", "Close", ["dismiss", "cancel", "x"], ["x", "dismiss", "cancel"]),
|
|
105
|
+
icon("action", "refresh", "Refresh", ["reload", "sync", "update"], ["reload", "sync"]),
|
|
106
|
+
icon("action", "open-in-new","Open in New", ["external", "launch", "popout"], ["external", "launch"], "open-in-new"),
|
|
107
|
+
icon("action", "drag-handle","Drag Handle", ["reorder", "grip", "move"], ["grip", "reorder"], "drag-indicator"),
|
|
108
|
+
icon("action", "more-horiz", "More", ["ellipsis", "overflow", "dots"], ["ellipsis", "dots", "three-dots"], "more-horiz"),
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
const NAVIGATION_ICONS: IconEntry[] = [
|
|
112
|
+
icon("navigation", "arrow-back", "Arrow Back", ["left", "previous", "return"], ["back", "left"], "arrow-back"),
|
|
113
|
+
icon("navigation", "arrow-forward", "Arrow Forward", ["right", "next", "proceed"], ["forward", "right"], "arrow-forward"),
|
|
114
|
+
icon("navigation", "arrow-upward", "Arrow Up", ["up", "ascend"], ["up"], "arrow-upward"),
|
|
115
|
+
icon("navigation", "arrow-downward", "Arrow Down", ["down", "descend"], ["down"], "arrow-downward"),
|
|
116
|
+
icon("navigation", "chevron-left", "Chevron Left", ["caret", "previous"], ["caret-left"], "chevron-left"),
|
|
117
|
+
icon("navigation", "chevron-right", "Chevron Right", ["caret", "next"], ["caret-right"], "chevron-right"),
|
|
118
|
+
icon("navigation", "chevron-down", "Chevron Down", ["caret", "dropdown"], ["caret-down"], "keyboard-arrow-down"),
|
|
119
|
+
icon("navigation", "chevron-up", "Chevron Up", ["caret", "collapse"], ["caret-up"], "keyboard-arrow-up"),
|
|
120
|
+
icon("navigation", "menu", "Menu", ["hamburger", "nav", "sidebar"], ["hamburger", "nav"]),
|
|
121
|
+
icon("navigation", "home", "Home", ["house", "main", "dashboard"], ["house", "dashboard"]),
|
|
122
|
+
icon("navigation", "expand-more", "Expand More", ["show-more", "dropdown"], [], "expand-more"),
|
|
123
|
+
icon("navigation", "expand-less", "Expand Less", ["show-less", "collapse"], [], "expand-less"),
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const CONTENT_ICONS: IconEntry[] = [
|
|
127
|
+
icon("content", "add-circle", "Add Circle", ["plus-circle", "create"], ["plus-circle"], "add-circle"),
|
|
128
|
+
icon("content", "flag", "Flag", ["report", "mark"], ["report"]),
|
|
129
|
+
icon("content", "bookmark", "Bookmark", ["save", "mark", "pin"], ["pin"]),
|
|
130
|
+
icon("content", "inbox", "Inbox", ["mailbox", "messages"], ["mailbox"]),
|
|
131
|
+
icon("content", "mail", "Mail", ["email", "envelope"], ["email", "envelope"]),
|
|
132
|
+
icon("content", "send", "Send", ["submit", "dispatch"], ["submit"]),
|
|
133
|
+
icon("content", "link", "Link", ["url", "chain", "hyperlink"], ["url", "chain"]),
|
|
134
|
+
icon("content", "unlink", "Unlink", ["break-link", "disconnect"], ["break-link"], "link-off"),
|
|
135
|
+
icon("content", "filter-list", "Filter", ["funnel", "sort", "sieve"], ["funnel", "filter"], "filter-list"),
|
|
136
|
+
icon("content", "sort", "Sort", ["order", "arrange"], ["order"]),
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
const STATUS_ICONS: IconEntry[] = [
|
|
140
|
+
icon("status", "check-circle", "Check Circle", ["success", "done", "complete"], ["success"], "check-circle"),
|
|
141
|
+
icon("status", "error", "Error", ["danger", "alert", "fail"], ["danger", "fail"]),
|
|
142
|
+
icon("status", "warning", "Warning", ["caution", "alert", "exclaim"], ["caution"]),
|
|
143
|
+
icon("status", "info", "Info", ["information", "about", "help"], ["information"]),
|
|
144
|
+
icon("status", "help", "Help", ["question", "support", "faq"], ["question"]),
|
|
145
|
+
icon("status", "pending", "Pending", ["waiting", "clock", "loading"], ["waiting", "clock"], "schedule"),
|
|
146
|
+
icon("status", "verified", "Verified", ["certified", "approved"], ["certified"], "verified"),
|
|
147
|
+
icon("status", "block", "Block", ["forbidden", "deny", "ban"], ["forbidden", "ban"]),
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
const MEDIA_ICONS: IconEntry[] = [
|
|
151
|
+
icon("media", "play", "Play", ["start", "resume"], ["start"]),
|
|
152
|
+
icon("media", "pause", "Pause", ["hold", "suspend"], ["hold"]),
|
|
153
|
+
icon("media", "stop", "Stop", ["halt", "end"], ["halt"]),
|
|
154
|
+
icon("media", "volume-up", "Volume Up", ["speaker", "sound", "loud"], ["speaker", "sound"], "volume-up"),
|
|
155
|
+
icon("media", "mic", "Microphone", ["record", "audio", "voice"], ["microphone", "record"]),
|
|
156
|
+
icon("media", "camera", "Camera", ["photo", "picture", "snap"], ["photo"]),
|
|
157
|
+
];
|
|
158
|
+
|
|
159
|
+
const FILE_ICONS: IconEntry[] = [
|
|
160
|
+
icon("file", "folder", "Folder", ["directory", "dir"], ["directory"]),
|
|
161
|
+
icon("file", "file", "File", ["document", "page"], ["document", "doc"], "description"),
|
|
162
|
+
icon("file", "attachment", "Attachment", ["paperclip", "attach"], ["paperclip"], "attach-file"),
|
|
163
|
+
icon("file", "cloud", "Cloud", ["storage", "online"], ["storage"]),
|
|
164
|
+
icon("file", "cloud-upload", "Cloud Upload", ["upload", "backup"], [], "cloud-upload"),
|
|
165
|
+
icon("file", "cloud-download", "Cloud Download", ["download", "restore"], [], "cloud-download"),
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
const SOCIAL_ICONS: IconEntry[] = [
|
|
169
|
+
icon("social", "person", "Person", ["user", "profile", "account"], ["user", "account"]),
|
|
170
|
+
icon("social", "group", "Group", ["team", "people", "users"], ["team", "people", "users"]),
|
|
171
|
+
icon("social", "share", "Share", ["distribute", "post"], []),
|
|
172
|
+
icon("social", "thumb-up", "Thumb Up", ["like", "approve", "upvote"], ["like", "upvote"], "thumb-up"),
|
|
173
|
+
icon("social", "thumb-down", "Thumb Down", ["dislike", "reject", "downvote"],["dislike", "downvote"],"thumb-down"),
|
|
174
|
+
icon("social", "notifications", "Notifications", ["bell", "alert", "notify"], ["bell", "alert"]),
|
|
175
|
+
];
|
|
176
|
+
|
|
177
|
+
const EDITOR_ICONS: IconEntry[] = [
|
|
178
|
+
icon("editor", "format-bold", "Bold", ["strong", "weight"], ["bold", "strong"], "format-bold"),
|
|
179
|
+
icon("editor", "format-italic", "Italic", ["emphasis", "slant"], ["italic"], "format-italic"),
|
|
180
|
+
icon("editor", "code", "Code", ["source", "develop"], ["source"]),
|
|
181
|
+
icon("editor", "text-fields", "Text", ["font", "type"], ["font", "type"], "text-fields"),
|
|
182
|
+
icon("editor", "format-list-bulleted", "Bulleted List", ["unordered", "ul"], ["ul", "bullet-list"], "format-list-bulleted"),
|
|
183
|
+
icon("editor", "format-list-numbered", "Numbered List", ["ordered", "ol"], ["ol", "number-list"], "format-list-numbered"),
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
const TOGGLE_ICONS: IconEntry[] = [
|
|
187
|
+
icon("toggle", "visibility", "Visibility", ["show", "eye", "visible"], ["show", "eye"]),
|
|
188
|
+
icon("toggle", "visibility-off", "Visibility Off", ["hide", "eye-off", "hidden"], ["hide", "eye-off"], "visibility-off"),
|
|
189
|
+
icon("toggle", "star", "Star", ["rate", "favorite", "rating"], ["rate"]),
|
|
190
|
+
icon("toggle", "favorite", "Favorite", ["heart", "love", "like"], ["heart", "love"]),
|
|
191
|
+
icon("toggle", "bookmark-border", "Bookmark Empty", ["save-outline", "unsaved"], ["bookmark-outline"], "bookmark-border"),
|
|
192
|
+
];
|
|
193
|
+
|
|
194
|
+
const DEVICE_ICONS: IconEntry[] = [
|
|
195
|
+
icon("device", "phone", "Phone", ["mobile", "cell", "smartphone"], ["mobile", "smartphone"], "smartphone"),
|
|
196
|
+
icon("device", "laptop", "Laptop", ["computer", "notebook", "pc"], ["computer", "notebook"], "laptop-mac"),
|
|
197
|
+
icon("device", "tablet", "Tablet", ["ipad", "pad"], ["ipad"], "tablet-mac"),
|
|
198
|
+
icon("device", "watch", "Watch", ["wearable", "smartwatch"], ["smartwatch"], "watch"),
|
|
199
|
+
];
|
|
200
|
+
|
|
201
|
+
const COMMUNICATION_ICONS: IconEntry[] = [
|
|
202
|
+
icon("communication", "call", "Call", ["phone", "dial", "ring"], ["phone", "dial"]),
|
|
203
|
+
icon("communication", "chat", "Chat", ["message", "conversation"], ["message", "im"], "chat-bubble"),
|
|
204
|
+
icon("communication", "email", "Email", ["mail", "envelope", "letter"], ["mail", "envelope"]),
|
|
205
|
+
icon("communication", "forum", "Forum", ["discuss", "thread", "comment"], ["discuss", "comments"]),
|
|
206
|
+
];
|
|
207
|
+
|
|
208
|
+
// ─── Assemble default catalog ──────────────────────────────────────────────
|
|
209
|
+
|
|
210
|
+
const ALL_ENTRIES: IconEntry[] = [
|
|
211
|
+
...ACTION_ICONS,
|
|
212
|
+
...NAVIGATION_ICONS,
|
|
213
|
+
...CONTENT_ICONS,
|
|
214
|
+
...STATUS_ICONS,
|
|
215
|
+
...MEDIA_ICONS,
|
|
216
|
+
...FILE_ICONS,
|
|
217
|
+
...SOCIAL_ICONS,
|
|
218
|
+
...EDITOR_ICONS,
|
|
219
|
+
...TOGGLE_ICONS,
|
|
220
|
+
...DEVICE_ICONS,
|
|
221
|
+
...COMMUNICATION_ICONS,
|
|
222
|
+
];
|
|
223
|
+
|
|
224
|
+
export const DEFAULT_ICON_CATALOG: IconCatalog = {
|
|
225
|
+
defaultLibrary: "material-symbols",
|
|
226
|
+
entries: ALL_ENTRIES,
|
|
227
|
+
customSets: [],
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// ─── Lookup & Search ───────────────────────────────────────────────────────
|
|
231
|
+
|
|
232
|
+
/** Exact match by canonical name (e.g. "icon/action/search"). */
|
|
233
|
+
export function getIconByName(name: string): IconEntry | null {
|
|
234
|
+
return ALL_ENTRIES.find((e) => e.name === name) ?? null;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Filter icons by category. */
|
|
238
|
+
export function getIconsByCategory(category: IconCategory): IconEntry[] {
|
|
239
|
+
return ALL_ENTRIES.filter((e) => e.category === category);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Score-based search across names, display names, tags, and aliases.
|
|
244
|
+
* Returns results sorted by relevance (higher score first).
|
|
245
|
+
* No external dependencies — uses substring + starts-with scoring.
|
|
246
|
+
*/
|
|
247
|
+
export function searchIcons(
|
|
248
|
+
query: string,
|
|
249
|
+
options?: { category?: IconCategory; limit?: number },
|
|
250
|
+
): IconEntry[] {
|
|
251
|
+
const q = query.toLowerCase().trim();
|
|
252
|
+
if (!q) return [];
|
|
253
|
+
|
|
254
|
+
const limit = options?.limit ?? 10;
|
|
255
|
+
let pool = options?.category
|
|
256
|
+
? ALL_ENTRIES.filter((e) => e.category === options.category)
|
|
257
|
+
: ALL_ENTRIES;
|
|
258
|
+
|
|
259
|
+
// Also search custom sets
|
|
260
|
+
for (const cs of DEFAULT_ICON_CATALOG.customSets) {
|
|
261
|
+
pool = pool.concat(
|
|
262
|
+
options?.category
|
|
263
|
+
? cs.icons.filter((e) => e.category === options.category)
|
|
264
|
+
: cs.icons,
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const scored: Array<{ entry: IconEntry; score: number }> = [];
|
|
269
|
+
|
|
270
|
+
for (const entry of pool) {
|
|
271
|
+
let score = 0;
|
|
272
|
+
|
|
273
|
+
// Exact slug match (highest priority)
|
|
274
|
+
const slug = entry.name.split("/").pop() ?? "";
|
|
275
|
+
if (slug === q) { score += 100; }
|
|
276
|
+
else if (slug.startsWith(q)) { score += 60; }
|
|
277
|
+
else if (slug.includes(q)) { score += 30; }
|
|
278
|
+
|
|
279
|
+
// Display name match
|
|
280
|
+
const dn = entry.displayName.toLowerCase();
|
|
281
|
+
if (dn === q) { score += 80; }
|
|
282
|
+
else if (dn.startsWith(q)) { score += 40; }
|
|
283
|
+
else if (dn.includes(q)) { score += 20; }
|
|
284
|
+
|
|
285
|
+
// Alias exact match (high priority — these are common user terms)
|
|
286
|
+
for (const alias of entry.aliases) {
|
|
287
|
+
if (alias === q) { score += 90; break; }
|
|
288
|
+
if (alias.startsWith(q)) { score += 45; break; }
|
|
289
|
+
if (alias.includes(q)) { score += 15; break; }
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Tag match
|
|
293
|
+
for (const tag of entry.tags) {
|
|
294
|
+
if (tag === q) { score += 50; break; }
|
|
295
|
+
if (tag.startsWith(q)) { score += 25; break; }
|
|
296
|
+
if (tag.includes(q)) { score += 10; break; }
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (score > 0) {
|
|
300
|
+
scored.push({ entry, score });
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
scored.sort((a, b) => b.score - a.score);
|
|
305
|
+
return scored.slice(0, limit).map((s) => s.entry);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// ─── Custom Icon Registration ──────────────────────────────────────────────
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Register a custom icon set at runtime. Enterprise teams call this at
|
|
312
|
+
* plugin startup to add their branded icons to the catalog.
|
|
313
|
+
*/
|
|
314
|
+
export function registerCustomIconSet(set: CustomIconSet): void {
|
|
315
|
+
// Prevent duplicate registration
|
|
316
|
+
const idx = DEFAULT_ICON_CATALOG.customSets.findIndex(
|
|
317
|
+
(cs) => cs.prefix === set.prefix,
|
|
318
|
+
);
|
|
319
|
+
if (idx >= 0) {
|
|
320
|
+
DEFAULT_ICON_CATALOG.customSets[idx] = set;
|
|
321
|
+
} else {
|
|
322
|
+
DEFAULT_ICON_CATALOG.customSets.push(set);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// ─── Iconify ID Resolution ─────────────────────────────────────────────────
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Resolve the full Iconify API identifier for an icon entry.
|
|
330
|
+
* For Material Symbols, appends "-outline" suffix for outlined variant.
|
|
331
|
+
*/
|
|
332
|
+
export function resolveIconifyId(
|
|
333
|
+
entry: IconEntry,
|
|
334
|
+
type: "filled" | "outlined" = "filled",
|
|
335
|
+
): string {
|
|
336
|
+
const base = entry.iconifyId;
|
|
337
|
+
if (type === "outlined" && entry.hasOutlined) {
|
|
338
|
+
// Material Symbols uses separate icon sets for filled vs outlined
|
|
339
|
+
return base.replace("material-symbols:", "material-symbols:") + "-outline";
|
|
340
|
+
}
|
|
341
|
+
return base;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Get all available icon categories with their entry counts.
|
|
346
|
+
*/
|
|
347
|
+
export function getIconCategorySummary(): Array<{ category: IconCategory; count: number }> {
|
|
348
|
+
const counts = new Map<IconCategory, number>();
|
|
349
|
+
for (const entry of ALL_ENTRIES) {
|
|
350
|
+
counts.set(entry.category, (counts.get(entry.category) ?? 0) + 1);
|
|
351
|
+
}
|
|
352
|
+
for (const cs of DEFAULT_ICON_CATALOG.customSets) {
|
|
353
|
+
for (const entry of cs.icons) {
|
|
354
|
+
counts.set(entry.category, (counts.get(entry.category) ?? 0) + 1);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return Array.from(counts.entries())
|
|
358
|
+
.map(([category, count]) => ({ category, count }))
|
|
359
|
+
.sort((a, b) => b.count - a.count);
|
|
360
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2
|
+
// Icon Fetch
|
|
3
|
+
// Shared SVG fetching utility for icons from Iconify and custom endpoints.
|
|
4
|
+
// Used by screen-cloner, component-script-builder, and other tools.
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
import type { IconEntry, CustomIconSet } from "./icon-catalog.js";
|
|
8
|
+
import { resolveIconifyId } from "./icon-catalog.js";
|
|
9
|
+
|
|
10
|
+
const ICONIFY_BASE = "https://api.iconify.design";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Fetch SVG for a catalog icon entry from Iconify.
|
|
14
|
+
* Returns raw SVG string or null on failure.
|
|
15
|
+
*/
|
|
16
|
+
export async function fetchIconSvg(
|
|
17
|
+
entry: IconEntry,
|
|
18
|
+
type: "filled" | "outlined" = "filled",
|
|
19
|
+
): Promise<string | null> {
|
|
20
|
+
const iconifyId = resolveIconifyId(entry, type);
|
|
21
|
+
const [prefix, name] = iconifyId.split(":");
|
|
22
|
+
if (!prefix || !name) return null;
|
|
23
|
+
|
|
24
|
+
const url = `${ICONIFY_BASE}/${encodeURIComponent(prefix)}/${encodeURIComponent(name)}.svg`;
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const response = await fetch(url);
|
|
28
|
+
if (!response.ok) return null;
|
|
29
|
+
return await response.text();
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Fetch SVG for a custom icon from an enterprise icon set.
|
|
37
|
+
* Tries inline svgMap first, then apiEndpoint if available.
|
|
38
|
+
*/
|
|
39
|
+
export async function fetchCustomIconSvg(
|
|
40
|
+
set: CustomIconSet,
|
|
41
|
+
iconName: string,
|
|
42
|
+
): Promise<string | null> {
|
|
43
|
+
// Try inline SVG map first
|
|
44
|
+
if (set.svgMap?.[iconName]) {
|
|
45
|
+
return set.svgMap[iconName];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Try API endpoint
|
|
49
|
+
if (set.apiEndpoint) {
|
|
50
|
+
const url = `${set.apiEndpoint}/${encodeURIComponent(iconName)}.svg`;
|
|
51
|
+
try {
|
|
52
|
+
const response = await fetch(url);
|
|
53
|
+
if (!response.ok) return null;
|
|
54
|
+
return await response.text();
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Fetch SVG by raw Iconify prefix:name identifier.
|
|
65
|
+
* Lower-level than fetchIconSvg — for use when you have a raw ID
|
|
66
|
+
* rather than an IconEntry.
|
|
67
|
+
*/
|
|
68
|
+
export async function fetchIconifySvg(
|
|
69
|
+
prefix: string,
|
|
70
|
+
name: string,
|
|
71
|
+
): Promise<string | null> {
|
|
72
|
+
const url = `${ICONIFY_BASE}/${encodeURIComponent(prefix)}/${encodeURIComponent(name)}.svg`;
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetch(url);
|
|
75
|
+
if (!response.ok) return null;
|
|
76
|
+
return await response.text();
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|