@3fn/core 13.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/.kiro/agents/ada-prompt.md +265 -0
- package/.kiro/agents/ada.json +87 -0
- package/.kiro/agents/data-prompt.md +315 -0
- package/.kiro/agents/data.json +58 -0
- package/.kiro/agents/kenya-prompt.md +298 -0
- package/.kiro/agents/kenya.json +54 -0
- package/.kiro/agents/leonardo-prompt.md +417 -0
- package/.kiro/agents/leonardo.json +55 -0
- package/.kiro/agents/lina-prompt.md +385 -0
- package/.kiro/agents/lina.json +77 -0
- package/.kiro/agents/sparky-prompt.md +295 -0
- package/.kiro/agents/sparky.json +56 -0
- package/.kiro/agents/stacy-prompt.md +278 -0
- package/.kiro/agents/stacy.json +48 -0
- package/.kiro/agents/thurgood-prompt.md +407 -0
- package/.kiro/agents/thurgood.json +51 -0
- package/.kiro/steering/AI-Collaboration-Principles.md +105 -0
- package/.kiro/steering/Agent-Directory.md +141 -0
- package/.kiro/steering/Civitas-System-Overview.md +134 -0
- package/.kiro/steering/DesignerPunk-Systems-Overview.md +318 -0
- package/.kiro/steering/Spec-Feedback-Protocol.md +242 -0
- package/.kiro/steering/Task-Completion-Protocol.md +73 -0
- package/.kiro/steering/core-goals.md +91 -0
- package/.kiro/steering/personal-note.md +35 -0
- package/.kiro/steering/start-up-tasks.md +114 -0
- package/LICENSE +201 -0
- package/README.md +184 -0
- package/application-mcp-server/package.json +34 -0
- package/application-mcp-server/src/__tests__/__mocks__/mcp-sdk-server.js +25 -0
- package/application-mcp-server/src/__tests__/__mocks__/mcp-sdk-stdio.js +11 -0
- package/application-mcp-server/src/__tests__/__mocks__/mcp-sdk-types.js +14 -0
- package/application-mcp-server/src/__tests__/tool-boundary.contract.test.ts +1086 -0
- package/application-mcp-server/src/index.ts +607 -0
- package/application-mcp-server/src/indexer/ComponentIndexer.ts +631 -0
- package/application-mcp-server/src/indexer/CompositionChecker.ts +109 -0
- package/application-mcp-server/src/indexer/ContractTokenDeriver.ts +68 -0
- package/application-mcp-server/src/indexer/DesignPhilosophyIndexer.ts +114 -0
- package/application-mcp-server/src/indexer/FamilyGuidanceIndexer.ts +248 -0
- package/application-mcp-server/src/indexer/InheritanceResolver.ts +154 -0
- package/application-mcp-server/src/indexer/LayoutTemplateIndexer.ts +254 -0
- package/application-mcp-server/src/indexer/ModeClassifier.ts +102 -0
- package/application-mcp-server/src/indexer/PatternIndexer.ts +195 -0
- package/application-mcp-server/src/indexer/TokenIndexer.ts +210 -0
- package/application-mcp-server/src/indexer/TokenRefResolver.ts +187 -0
- package/application-mcp-server/src/indexer/__tests__/ComponentIndexer.test.ts +141 -0
- package/application-mcp-server/src/indexer/__tests__/CompositionChecker.test.ts +148 -0
- package/application-mcp-server/src/indexer/__tests__/ContractTokenDeriver.test.ts +111 -0
- package/application-mcp-server/src/indexer/__tests__/CoverageDrift.test.ts +53 -0
- package/application-mcp-server/src/indexer/__tests__/DesignPhilosophyIndexer.test.ts +102 -0
- package/application-mcp-server/src/indexer/__tests__/FamilyGuidanceIndexer.test.ts +316 -0
- package/application-mcp-server/src/indexer/__tests__/FamilyNameValidation.test.ts +98 -0
- package/application-mcp-server/src/indexer/__tests__/GuidanceCompleteness.test.ts +63 -0
- package/application-mcp-server/src/indexer/__tests__/HealthStates.test.ts +129 -0
- package/application-mcp-server/src/indexer/__tests__/InheritanceResolver.test.ts +145 -0
- package/application-mcp-server/src/indexer/__tests__/LayoutTemplateIndexer.test.ts +378 -0
- package/application-mcp-server/src/indexer/__tests__/PatternIndexer.test.ts +323 -0
- package/application-mcp-server/src/indexer/__tests__/ReadinessCompliance.test.ts +212 -0
- package/application-mcp-server/src/indexer/__tests__/TokenIndexer.test.ts +131 -0
- package/application-mcp-server/src/indexer/__tests__/fixtures/design-philosophy.yaml +40 -0
- package/application-mcp-server/src/indexer/__tests__/parsers.test.ts +102 -0
- package/application-mcp-server/src/indexer/parsers.ts +284 -0
- package/application-mcp-server/src/models/index.ts +449 -0
- package/application-mcp-server/src/query/QueryEngine.ts +477 -0
- package/application-mcp-server/src/query/__tests__/QueryEngine.test.ts +282 -0
- package/application-mcp-server/src/query/__tests__/deriveMatchConfidence.test.ts +83 -0
- package/application-mcp-server/src/staleness/StalenessGate.ts +112 -0
- package/application-mcp-server/src/staleness/__tests__/GateIntegration.test.ts +141 -0
- package/application-mcp-server/src/staleness/__tests__/StalenessGate.test.ts +214 -0
- package/application-mcp-server/src/validation/AccessibilityChecker.ts +72 -0
- package/application-mcp-server/src/validation/AssemblyValidator.ts +77 -0
- package/application-mcp-server/src/validation/__tests__/AccessibilityChecker.test.ts +105 -0
- package/application-mcp-server/src/validation/__tests__/AssemblyValidator.test.ts +140 -0
- package/application-mcp-server/src/watcher/FileWatcher.ts +104 -0
- package/application-mcp-server/src/watcher/__tests__/FileWatcher.test.ts +59 -0
- package/application-mcp-server/tsconfig.json +24 -0
- package/bin/designerpunk.js +45 -0
- package/design-language/design-philosophy.yaml +139 -0
- package/designerpunk.config.ts +27 -0
- package/dist/ComponentTokens.android.kt +105 -0
- package/dist/ComponentTokens.ios.swift +105 -0
- package/dist/ComponentTokens.web.css +92 -0
- package/dist/DesignTokens.android.kt +696 -0
- package/dist/DesignTokens.dtcg.json +5759 -0
- package/dist/DesignTokens.figma.json +5053 -0
- package/dist/DesignTokens.ios.swift +696 -0
- package/dist/DesignTokens.web.css +940 -0
- package/dist/TokenEngine.d.ts +200 -0
- package/dist/TokenEngine.js +480 -0
- package/dist/__tests__/fixtures/acknowledged-differences.json +127 -0
- package/dist/analytics/PrimitiveTokenFallbackTracker.d.ts +91 -0
- package/dist/analytics/PrimitiveTokenFallbackTracker.js +168 -0
- package/dist/analytics/SemanticTokenUsageTracker.d.ts +79 -0
- package/dist/analytics/SemanticTokenUsageTracker.js +142 -0
- package/dist/analytics/StrategicFlexibilityTracker.d.ts +99 -0
- package/dist/analytics/StrategicFlexibilityTracker.js +165 -0
- package/dist/analytics/TokenUsageTracker.d.ts +87 -0
- package/dist/analytics/TokenUsageTracker.js +128 -0
- package/dist/analytics/UsagePatternAnalyzer.d.ts +64 -0
- package/dist/analytics/UsagePatternAnalyzer.js +126 -0
- package/dist/analytics/index.d.ts +15 -0
- package/dist/analytics/index.js +27 -0
- package/dist/android/DesignTokens.android.kt +695 -0
- package/dist/blend/BlendCalculator.d.ts +65 -0
- package/dist/blend/BlendCalculator.js +98 -0
- package/dist/blend/ColorSpaceUtils.d.ts +164 -0
- package/dist/blend/ColorSpaceUtils.js +292 -0
- package/dist/blend/OklchBlendCalculator.d.ts +64 -0
- package/dist/blend/OklchBlendCalculator.js +77 -0
- package/dist/blend/ThemeAwareBlendUtilities.web.d.ts +202 -0
- package/dist/blend/ThemeAwareBlendUtilities.web.js +212 -0
- package/dist/blend/index.d.ts +12 -0
- package/dist/blend/index.js +30 -0
- package/dist/browser/demo-styles.css +492 -0
- package/dist/browser/designerpunk.esm.js +18472 -0
- package/dist/browser/designerpunk.esm.min.js +705 -0
- package/dist/browser/designerpunk.umd.js +18540 -0
- package/dist/browser/designerpunk.umd.min.js +705 -0
- package/dist/browser/tokens.css +1028 -0
- package/dist/browser-entry.d.ts +82 -0
- package/dist/browser-entry.js +297 -0
- package/dist/build/BuildOrchestrator.d.ts +89 -0
- package/dist/build/BuildOrchestrator.js +583 -0
- package/dist/build/errors/BuildError.d.ts +87 -0
- package/dist/build/errors/BuildError.js +67 -0
- package/dist/build/errors/ErrorDocumentation.d.ts +66 -0
- package/dist/build/errors/ErrorDocumentation.js +557 -0
- package/dist/build/errors/ErrorHandler.d.ts +120 -0
- package/dist/build/errors/ErrorHandler.js +299 -0
- package/dist/build/errors/ErrorReporter.d.ts +102 -0
- package/dist/build/errors/ErrorReporter.js +397 -0
- package/dist/build/errors/PlatformGenerationError.d.ts +73 -0
- package/dist/build/errors/PlatformGenerationError.js +163 -0
- package/dist/build/errors/RecoveryStrategy.d.ts +145 -0
- package/dist/build/errors/RecoveryStrategy.js +297 -0
- package/dist/build/errors/TokenGenerationError.d.ts +65 -0
- package/dist/build/errors/TokenGenerationError.js +161 -0
- package/dist/build/errors/TokenReferenceError.d.ts +65 -0
- package/dist/build/errors/TokenReferenceError.js +168 -0
- package/dist/build/errors/index.d.ts +18 -0
- package/dist/build/errors/index.js +63 -0
- package/dist/build/index.d.ts +19 -0
- package/dist/build/index.js +26 -0
- package/dist/build/orchestration/IncrementalBuilder.d.ts +180 -0
- package/dist/build/orchestration/IncrementalBuilder.js +393 -0
- package/dist/build/orchestration/ParallelExecutor.d.ts +87 -0
- package/dist/build/orchestration/ParallelExecutor.js +242 -0
- package/dist/build/orchestration/ProgressTracker.d.ts +181 -0
- package/dist/build/orchestration/ProgressTracker.js +371 -0
- package/dist/build/orchestration/SequentialExecutor.d.ts +96 -0
- package/dist/build/orchestration/SequentialExecutor.js +211 -0
- package/dist/build/orchestration/index.d.ts +10 -0
- package/dist/build/orchestration/index.js +17 -0
- package/dist/build/platforms/AndroidBuilder.d.ts +288 -0
- package/dist/build/platforms/AndroidBuilder.js +1134 -0
- package/dist/build/platforms/AndroidShadowGenerator.d.ts +101 -0
- package/dist/build/platforms/AndroidShadowGenerator.js +298 -0
- package/dist/build/platforms/IOSShadowGenerator.d.ts +84 -0
- package/dist/build/platforms/IOSShadowGenerator.js +254 -0
- package/dist/build/platforms/PlatformBuilder.d.ts +111 -0
- package/dist/build/platforms/PlatformBuilder.js +10 -0
- package/dist/build/platforms/WebBuilder.d.ts +294 -0
- package/dist/build/platforms/WebBuilder.js +1133 -0
- package/dist/build/platforms/WebShadowGenerator.d.ts +78 -0
- package/dist/build/platforms/WebShadowGenerator.js +226 -0
- package/dist/build/platforms/iOSBuilder.d.ts +352 -0
- package/dist/build/platforms/iOSBuilder.js +1461 -0
- package/dist/build/platforms/index.d.ts +8 -0
- package/dist/build/platforms/index.js +24 -0
- package/dist/build/product/ProductTokenGenerator.d.ts +62 -0
- package/dist/build/product/ProductTokenGenerator.js +141 -0
- package/dist/build/product/TokenIndexReader.d.ts +28 -0
- package/dist/build/product/TokenIndexReader.js +101 -0
- package/dist/build/product/emitters/KotlinEmitter.d.ts +8 -0
- package/dist/build/product/emitters/KotlinEmitter.js +80 -0
- package/dist/build/product/emitters/SwiftEmitter.d.ts +8 -0
- package/dist/build/product/emitters/SwiftEmitter.js +87 -0
- package/dist/build/product/emitters/WebEmitter.d.ts +8 -0
- package/dist/build/product/emitters/WebEmitter.js +66 -0
- package/dist/build/tokens/ComponentToken.d.ts +239 -0
- package/dist/build/tokens/ComponentToken.js +51 -0
- package/dist/build/tokens/ComponentTokenGenerator.d.ts +117 -0
- package/dist/build/tokens/ComponentTokenGenerator.js +324 -0
- package/dist/build/tokens/PlatformTokens.d.ts +144 -0
- package/dist/build/tokens/PlatformTokens.js +9 -0
- package/dist/build/tokens/TokenIntegrator.d.ts +156 -0
- package/dist/build/tokens/TokenIntegrator.js +259 -0
- package/dist/build/tokens/TokenSelection.d.ts +105 -0
- package/dist/build/tokens/TokenSelection.js +9 -0
- package/dist/build/tokens/TokenSelector.d.ts +73 -0
- package/dist/build/tokens/TokenSelector.js +336 -0
- package/dist/build/tokens/UnitConverter.d.ts +126 -0
- package/dist/build/tokens/UnitConverter.js +222 -0
- package/dist/build/tokens/defineComponentTokens.d.ts +186 -0
- package/dist/build/tokens/defineComponentTokens.js +193 -0
- package/dist/build/tokens/index.d.ts +18 -0
- package/dist/build/tokens/index.js +23 -0
- package/dist/build/tokens/types.d.ts +24 -0
- package/dist/build/tokens/types.js +8 -0
- package/dist/build/types/BuildConfig.d.ts +92 -0
- package/dist/build/types/BuildConfig.js +28 -0
- package/dist/build/types/BuildOrchestrator.d.ts +95 -0
- package/dist/build/types/BuildOrchestrator.js +9 -0
- package/dist/build/types/BuildResult.d.ts +91 -0
- package/dist/build/types/BuildResult.js +10 -0
- package/dist/build/types/Platform.d.ts +25 -0
- package/dist/build/types/Platform.js +39 -0
- package/dist/build/types/index.d.ts +14 -0
- package/dist/build/types/index.js +15 -0
- package/dist/build/validation/AndroidBuildValidator.d.ts +77 -0
- package/dist/build/validation/AndroidBuildValidator.js +562 -0
- package/dist/build/validation/CrossPlatformValidationReporter.d.ts +295 -0
- package/dist/build/validation/CrossPlatformValidationReporter.js +817 -0
- package/dist/build/validation/InterfaceContractValidator.d.ts +102 -0
- package/dist/build/validation/InterfaceContractValidator.js +303 -0
- package/dist/build/validation/InterfaceValidator.d.ts +48 -0
- package/dist/build/validation/InterfaceValidator.js +214 -0
- package/dist/build/validation/MathematicalConsistencyValidator.d.ts +194 -0
- package/dist/build/validation/MathematicalConsistencyValidator.js +656 -0
- package/dist/build/validation/MethodSignatureValidator.d.ts +72 -0
- package/dist/build/validation/MethodSignatureValidator.js +283 -0
- package/dist/build/validation/PropertyTypeValidator.d.ts +73 -0
- package/dist/build/validation/PropertyTypeValidator.js +241 -0
- package/dist/build/validation/TokenComparator.d.ts +221 -0
- package/dist/build/validation/TokenComparator.js +478 -0
- package/dist/build/validation/ValidationReporter.d.ts +173 -0
- package/dist/build/validation/ValidationReporter.example.d.ts +17 -0
- package/dist/build/validation/ValidationReporter.example.js +259 -0
- package/dist/build/validation/ValidationReporter.js +517 -0
- package/dist/build/validation/WebBuildValidator.d.ts +112 -0
- package/dist/build/validation/WebBuildValidator.js +470 -0
- package/dist/build/validation/iOSBuildValidator.d.ts +155 -0
- package/dist/build/validation/iOSBuildValidator.js +670 -0
- package/dist/build/validation/index.d.ts +26 -0
- package/dist/build/validation/index.js +34 -0
- package/dist/build/validation/types/InterfaceDefinition.d.ts +74 -0
- package/dist/build/validation/types/InterfaceDefinition.js +9 -0
- package/dist/build/validation/types/ValidationResult.d.ts +74 -0
- package/dist/build/validation/types/ValidationResult.js +9 -0
- package/dist/build/workflow/BuildMode.d.ts +147 -0
- package/dist/build/workflow/BuildMode.js +205 -0
- package/dist/build/workflow/CICDIntegration.d.ts +179 -0
- package/dist/build/workflow/CICDIntegration.js +347 -0
- package/dist/build/workflow/ConfigHelpers.d.ts +139 -0
- package/dist/build/workflow/ConfigHelpers.example.d.ts +8 -0
- package/dist/build/workflow/ConfigHelpers.example.js +269 -0
- package/dist/build/workflow/ConfigHelpers.js +714 -0
- package/dist/build/workflow/SourceMapGenerator.d.ts +89 -0
- package/dist/build/workflow/SourceMapGenerator.js +268 -0
- package/dist/build/workflow/index.d.ts +13 -0
- package/dist/build/workflow/index.js +23 -0
- package/dist/cli/designerpunk.d.ts +20 -0
- package/dist/cli/designerpunk.js +416 -0
- package/dist/cli/figma-extract.d.ts +64 -0
- package/dist/cli/figma-extract.js +338 -0
- package/dist/cli/figma-push.d.ts +63 -0
- package/dist/cli/figma-push.js +292 -0
- package/dist/cli/generateProductTokens.d.ts +11 -0
- package/dist/cli/generateProductTokens.js +96 -0
- package/dist/cli/init.d.ts +11 -0
- package/dist/cli/init.js +385 -0
- package/dist/cli/loadComponentTokens.d.ts +46 -0
- package/dist/cli/loadComponentTokens.js +163 -0
- package/dist/cli/resolveTokens.d.ts +40 -0
- package/dist/cli/resolveTokens.js +94 -0
- package/dist/cli/shared/mcpDataRoots.d.ts +38 -0
- package/dist/cli/shared/mcpDataRoots.js +75 -0
- package/dist/cli/shared/resolvePackageRoot.d.ts +2 -0
- package/dist/cli/shared/resolvePackageRoot.js +50 -0
- package/dist/cli/shared/transforms.d.ts +13 -0
- package/dist/cli/shared/transforms.js +18 -0
- package/dist/cli/staleness.d.ts +23 -0
- package/dist/cli/staleness.js +113 -0
- package/dist/cli/sync/Applier.d.ts +32 -0
- package/dist/cli/sync/Applier.js +127 -0
- package/dist/cli/sync/Classifier.d.ts +27 -0
- package/dist/cli/sync/Classifier.js +103 -0
- package/dist/cli/sync/FileScanner.d.ts +19 -0
- package/dist/cli/sync/FileScanner.js +82 -0
- package/dist/cli/sync/IgnoreFilter.d.ts +10 -0
- package/dist/cli/sync/IgnoreFilter.js +70 -0
- package/dist/cli/sync/Manifest.d.ts +24 -0
- package/dist/cli/sync/Manifest.js +85 -0
- package/dist/cli/sync/PackageResolver.d.ts +14 -0
- package/dist/cli/sync/PackageResolver.js +67 -0
- package/dist/cli/sync/Prompter.d.ts +22 -0
- package/dist/cli/sync/Prompter.js +169 -0
- package/dist/cli/sync/Reporter.d.ts +11 -0
- package/dist/cli/sync/Reporter.js +66 -0
- package/dist/cli/sync/SteeringDirCheck.d.ts +50 -0
- package/dist/cli/sync/SteeringDirCheck.js +174 -0
- package/dist/cli/sync/index.d.ts +14 -0
- package/dist/cli/sync/index.js +94 -0
- package/dist/cli/validate.d.ts +18 -0
- package/dist/cli/validate.js +147 -0
- package/dist/cli/validateProductTokens.d.ts +10 -0
- package/dist/cli/validateProductTokens.js +84 -0
- package/dist/color/OklchConverter.d.ts +50 -0
- package/dist/color/OklchConverter.js +242 -0
- package/dist/color/OklchValidator.d.ts +49 -0
- package/dist/color/OklchValidator.js +147 -0
- package/dist/components/core/Avatar-Base/avatar.tokens.d.ts +327 -0
- package/dist/components/core/Avatar-Base/avatar.tokens.js +344 -0
- package/dist/components/core/Avatar-Base/index.d.ts +12 -0
- package/dist/components/core/Avatar-Base/index.js +24 -0
- package/dist/components/core/Avatar-Base/platforms/web/Avatar.web.d.ts +315 -0
- package/dist/components/core/Avatar-Base/platforms/web/Avatar.web.js +803 -0
- package/dist/components/core/Avatar-Base/types.d.ts +72 -0
- package/dist/components/core/Avatar-Base/types.js +21 -0
- package/dist/components/core/Badge-Count-Base/index.d.ts +24 -0
- package/dist/components/core/Badge-Count-Base/index.js +36 -0
- package/dist/components/core/Badge-Count-Base/platforms/web/BadgeCountBase.web.d.ts +192 -0
- package/dist/components/core/Badge-Count-Base/platforms/web/BadgeCountBase.web.js +337 -0
- package/dist/components/core/Badge-Count-Base/types.d.ts +137 -0
- package/dist/components/core/Badge-Count-Base/types.js +67 -0
- package/dist/components/core/Badge-Count-Notification/index.d.ts +33 -0
- package/dist/components/core/Badge-Count-Notification/index.js +56 -0
- package/dist/components/core/Badge-Count-Notification/platforms/web/BadgeCountNotification.web.d.ts +179 -0
- package/dist/components/core/Badge-Count-Notification/platforms/web/BadgeCountNotification.web.js +365 -0
- package/dist/components/core/Badge-Count-Notification/tokens.d.ts +118 -0
- package/dist/components/core/Badge-Count-Notification/tokens.js +120 -0
- package/dist/components/core/Badge-Count-Notification/types.d.ts +112 -0
- package/dist/components/core/Badge-Count-Notification/types.js +33 -0
- package/dist/components/core/Badge-Label-Base/index.d.ts +24 -0
- package/dist/components/core/Badge-Label-Base/index.js +39 -0
- package/dist/components/core/Badge-Label-Base/platforms/web/BadgeLabelBase.web.d.ts +178 -0
- package/dist/components/core/Badge-Label-Base/platforms/web/BadgeLabelBase.web.js +315 -0
- package/dist/components/core/Badge-Label-Base/tokens.d.ts +69 -0
- package/dist/components/core/Badge-Label-Base/tokens.js +81 -0
- package/dist/components/core/Badge-Label-Base/types.d.ts +139 -0
- package/dist/components/core/Badge-Label-Base/types.js +61 -0
- package/dist/components/core/Button-CTA/Button-CTA.tokens.d.ts +73 -0
- package/dist/components/core/Button-CTA/Button-CTA.tokens.js +75 -0
- package/dist/components/core/Button-CTA/examples/BasicUsage.d.ts +146 -0
- package/dist/components/core/Button-CTA/examples/BasicUsage.js +231 -0
- package/dist/components/core/Button-CTA/index.d.ts +14 -0
- package/dist/components/core/Button-CTA/index.js +20 -0
- package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.d.ts +273 -0
- package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.js +635 -0
- package/dist/components/core/Button-CTA/types.d.ts +247 -0
- package/dist/components/core/Button-CTA/types.js +14 -0
- package/dist/components/core/Button-Icon/buttonIcon.tokens.d.ts +171 -0
- package/dist/components/core/Button-Icon/buttonIcon.tokens.js +188 -0
- package/dist/components/core/Button-Icon/platforms/web/ButtonIcon.web.d.ts +267 -0
- package/dist/components/core/Button-Icon/platforms/web/ButtonIcon.web.js +570 -0
- package/dist/components/core/Button-Icon/types.d.ts +177 -0
- package/dist/components/core/Button-Icon/types.js +35 -0
- package/dist/components/core/Button-VerticalList-Item/Button-VerticalList-Item.tokens.d.ts +96 -0
- package/dist/components/core/Button-VerticalList-Item/Button-VerticalList-Item.tokens.js +107 -0
- package/dist/components/core/Button-VerticalList-Item/index.d.ts +19 -0
- package/dist/components/core/Button-VerticalList-Item/index.js +39 -0
- package/dist/components/core/Button-VerticalList-Item/platforms/web/ButtonVerticalListItem.web.d.ts +378 -0
- package/dist/components/core/Button-VerticalList-Item/platforms/web/ButtonVerticalListItem.web.js +916 -0
- package/dist/components/core/Button-VerticalList-Item/platforms/web/visualStateMapping.d.ts +227 -0
- package/dist/components/core/Button-VerticalList-Item/platforms/web/visualStateMapping.js +370 -0
- package/dist/components/core/Button-VerticalList-Item/types.d.ts +301 -0
- package/dist/components/core/Button-VerticalList-Item/types.js +16 -0
- package/dist/components/core/Button-VerticalList-Set/index.d.ts +16 -0
- package/dist/components/core/Button-VerticalList-Set/index.js +26 -0
- package/dist/components/core/Button-VerticalList-Set/platforms/web/ButtonVerticalListSet.web.d.ts +492 -0
- package/dist/components/core/Button-VerticalList-Set/platforms/web/ButtonVerticalListSet.web.js +1263 -0
- package/dist/components/core/Button-VerticalList-Set/types.d.ts +586 -0
- package/dist/components/core/Button-VerticalList-Set/types.js +375 -0
- package/dist/components/core/Chip-Base/index.d.ts +28 -0
- package/dist/components/core/Chip-Base/index.js +40 -0
- package/dist/components/core/Chip-Base/platforms/web/ChipBase.web.d.ts +214 -0
- package/dist/components/core/Chip-Base/platforms/web/ChipBase.web.js +434 -0
- package/dist/components/core/Chip-Base/types.d.ts +174 -0
- package/dist/components/core/Chip-Base/types.js +34 -0
- package/dist/components/core/Chip-Filter/index.d.ts +22 -0
- package/dist/components/core/Chip-Filter/index.js +31 -0
- package/dist/components/core/Chip-Filter/platforms/web/ChipFilter.web.d.ts +222 -0
- package/dist/components/core/Chip-Filter/platforms/web/ChipFilter.web.js +467 -0
- package/dist/components/core/Chip-Filter/types.d.ts +45 -0
- package/dist/components/core/Chip-Filter/types.js +19 -0
- package/dist/components/core/Chip-Input/index.d.ts +22 -0
- package/dist/components/core/Chip-Input/index.js +31 -0
- package/dist/components/core/Chip-Input/platforms/web/ChipInput.web.d.ts +205 -0
- package/dist/components/core/Chip-Input/platforms/web/ChipInput.web.js +419 -0
- package/dist/components/core/Chip-Input/types.d.ts +34 -0
- package/dist/components/core/Chip-Input/types.js +19 -0
- package/dist/components/core/Container-Base/index.d.ts +19 -0
- package/dist/components/core/Container-Base/index.js +34 -0
- package/dist/components/core/Container-Base/platforms/web/ContainerBase.web.d.ts +128 -0
- package/dist/components/core/Container-Base/platforms/web/ContainerBase.web.js +349 -0
- package/dist/components/core/Container-Base/platforms/web/token-mapping.d.ts +357 -0
- package/dist/components/core/Container-Base/platforms/web/token-mapping.js +518 -0
- package/dist/components/core/Container-Base/tokens.d.ts +179 -0
- package/dist/components/core/Container-Base/tokens.js +221 -0
- package/dist/components/core/Container-Base/types.d.ts +237 -0
- package/dist/components/core/Container-Base/types.js +50 -0
- package/dist/components/core/Container-Card-Base/index.d.ts +18 -0
- package/dist/components/core/Container-Card-Base/index.js +49 -0
- package/dist/components/core/Container-Card-Base/platforms/web/ContainerCardBase.web.d.ts +58 -0
- package/dist/components/core/Container-Card-Base/platforms/web/ContainerCardBase.web.js +324 -0
- package/dist/components/core/Container-Card-Base/tokens.d.ts +149 -0
- package/dist/components/core/Container-Card-Base/tokens.js +207 -0
- package/dist/components/core/Container-Card-Base/types.d.ts +268 -0
- package/dist/components/core/Container-Card-Base/types.js +85 -0
- package/dist/components/core/Icon-Base/index.d.ts +14 -0
- package/dist/components/core/Icon-Base/index.js +27 -0
- package/dist/components/core/Icon-Base/platforms/web/IconBase.web.d.ts +175 -0
- package/dist/components/core/Icon-Base/platforms/web/IconBase.web.js +503 -0
- package/dist/components/core/Icon-Base/types.d.ts +276 -0
- package/dist/components/core/Icon-Base/types.js +69 -0
- package/dist/components/core/Input-Checkbox-Base/checkbox-sizing.tokens.d.ts +30 -0
- package/dist/components/core/Input-Checkbox-Base/checkbox-sizing.tokens.js +39 -0
- package/dist/components/core/Input-Checkbox-Base/platforms/web/InputCheckboxBase.web.d.ts +147 -0
- package/dist/components/core/Input-Checkbox-Base/platforms/web/InputCheckboxBase.web.js +486 -0
- package/dist/components/core/Input-Checkbox-Base/types.d.ts +357 -0
- package/dist/components/core/Input-Checkbox-Base/types.js +60 -0
- package/dist/components/core/Input-Checkbox-Legal/platforms/web/InputCheckboxLegal.web.d.ts +110 -0
- package/dist/components/core/Input-Checkbox-Legal/platforms/web/InputCheckboxLegal.web.js +423 -0
- package/dist/components/core/Input-Checkbox-Legal/types.d.ts +311 -0
- package/dist/components/core/Input-Checkbox-Legal/types.js +69 -0
- package/dist/components/core/Input-Radio-Base/platforms/web/InputRadioBase.web.d.ts +250 -0
- package/dist/components/core/Input-Radio-Base/platforms/web/InputRadioBase.web.js +564 -0
- package/dist/components/core/Input-Radio-Base/radio-sizing.tokens.d.ts +30 -0
- package/dist/components/core/Input-Radio-Base/radio-sizing.tokens.js +39 -0
- package/dist/components/core/Input-Radio-Base/types.d.ts +327 -0
- package/dist/components/core/Input-Radio-Base/types.js +63 -0
- package/dist/components/core/Input-Radio-Set/platforms/web/InputRadioSet.web.d.ts +304 -0
- package/dist/components/core/Input-Radio-Set/platforms/web/InputRadioSet.web.js +691 -0
- package/dist/components/core/Input-Radio-Set/types.d.ts +275 -0
- package/dist/components/core/Input-Radio-Set/types.js +70 -0
- package/dist/components/core/Input-Text-Base/platforms/web/InputTextBase.browser.d.ts +26 -0
- package/dist/components/core/Input-Text-Base/platforms/web/InputTextBase.browser.js +224 -0
- package/dist/components/core/Input-Text-Base/platforms/web/InputTextBase.web.d.ts +116 -0
- package/dist/components/core/Input-Text-Base/platforms/web/InputTextBase.web.js +394 -0
- package/dist/components/core/Input-Text-Base/stateManagement.d.ts +172 -0
- package/dist/components/core/Input-Text-Base/stateManagement.js +224 -0
- package/dist/components/core/Input-Text-Base/tokens.d.ts +331 -0
- package/dist/components/core/Input-Text-Base/tokens.js +164 -0
- package/dist/components/core/Input-Text-Base/types.d.ts +77 -0
- package/dist/components/core/Input-Text-Base/types.js +13 -0
- package/dist/components/core/Input-Text-Email/platforms/web/InputTextEmail.browser.d.ts +30 -0
- package/dist/components/core/Input-Text-Email/platforms/web/InputTextEmail.browser.js +254 -0
- package/dist/components/core/Input-Text-Email/platforms/web/InputTextEmail.web.d.ts +105 -0
- package/dist/components/core/Input-Text-Email/platforms/web/InputTextEmail.web.js +279 -0
- package/dist/components/core/Input-Text-Email/stateManagement.d.ts +79 -0
- package/dist/components/core/Input-Text-Email/stateManagement.js +136 -0
- package/dist/components/core/Input-Text-Email/tokens.d.ts +20 -0
- package/dist/components/core/Input-Text-Email/tokens.js +34 -0
- package/dist/components/core/Input-Text-Email/types.d.ts +63 -0
- package/dist/components/core/Input-Text-Email/types.js +13 -0
- package/dist/components/core/Input-Text-Email/validation.d.ts +68 -0
- package/dist/components/core/Input-Text-Email/validation.js +115 -0
- package/dist/components/core/Input-Text-Password/platforms/web/InputTextPassword.browser.d.ts +44 -0
- package/dist/components/core/Input-Text-Password/platforms/web/InputTextPassword.browser.js +376 -0
- package/dist/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.d.ts +137 -0
- package/dist/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.js +447 -0
- package/dist/components/core/Input-Text-Password/stateManagement.d.ts +119 -0
- package/dist/components/core/Input-Text-Password/stateManagement.js +200 -0
- package/dist/components/core/Input-Text-Password/tokens.d.ts +20 -0
- package/dist/components/core/Input-Text-Password/tokens.js +34 -0
- package/dist/components/core/Input-Text-Password/types.d.ts +145 -0
- package/dist/components/core/Input-Text-Password/types.js +13 -0
- package/dist/components/core/Input-Text-Password/validation.d.ts +81 -0
- package/dist/components/core/Input-Text-Password/validation.js +170 -0
- package/dist/components/core/Input-Text-PhoneNumber/platforms/web/InputTextPhoneNumber.browser.d.ts +38 -0
- package/dist/components/core/Input-Text-PhoneNumber/platforms/web/InputTextPhoneNumber.browser.js +328 -0
- package/dist/components/core/Input-Text-PhoneNumber/platforms/web/InputTextPhoneNumber.web.d.ts +125 -0
- package/dist/components/core/Input-Text-PhoneNumber/platforms/web/InputTextPhoneNumber.web.js +334 -0
- package/dist/components/core/Input-Text-PhoneNumber/stateManagement.d.ts +114 -0
- package/dist/components/core/Input-Text-PhoneNumber/stateManagement.js +200 -0
- package/dist/components/core/Input-Text-PhoneNumber/tokens.d.ts +20 -0
- package/dist/components/core/Input-Text-PhoneNumber/tokens.js +34 -0
- package/dist/components/core/Input-Text-PhoneNumber/types.d.ts +111 -0
- package/dist/components/core/Input-Text-PhoneNumber/types.js +13 -0
- package/dist/components/core/Input-Text-PhoneNumber/validation.d.ts +120 -0
- package/dist/components/core/Input-Text-PhoneNumber/validation.js +278 -0
- package/dist/components/core/Nav-Header-App/index.d.ts +6 -0
- package/dist/components/core/Nav-Header-App/index.js +3 -0
- package/dist/components/core/Nav-Header-App/platforms/web/NavHeaderApp.web.d.ts +12 -0
- package/dist/components/core/Nav-Header-App/platforms/web/NavHeaderApp.web.js +34 -0
- package/dist/components/core/Nav-Header-App/types.d.ts +27 -0
- package/dist/components/core/Nav-Header-App/types.js +15 -0
- package/dist/components/core/Nav-Header-Base/index.d.ts +7 -0
- package/dist/components/core/Nav-Header-Base/index.js +8 -0
- package/dist/components/core/Nav-Header-Base/platforms/web/NavHeaderBase.web.d.ts +26 -0
- package/dist/components/core/Nav-Header-Base/platforms/web/NavHeaderBase.web.js +105 -0
- package/dist/components/core/Nav-Header-Base/types.d.ts +63 -0
- package/dist/components/core/Nav-Header-Base/types.js +17 -0
- package/dist/components/core/Nav-Header-Page/index.d.ts +7 -0
- package/dist/components/core/Nav-Header-Page/index.js +8 -0
- package/dist/components/core/Nav-Header-Page/platforms/web/NavHeaderPage.web.d.ts +31 -0
- package/dist/components/core/Nav-Header-Page/platforms/web/NavHeaderPage.web.js +148 -0
- package/dist/components/core/Nav-Header-Page/types.d.ts +46 -0
- package/dist/components/core/Nav-Header-Page/types.js +16 -0
- package/dist/components/core/Nav-SegmentedChoice-Base/index.d.ts +25 -0
- package/dist/components/core/Nav-SegmentedChoice-Base/index.js +33 -0
- package/dist/components/core/Nav-SegmentedChoice-Base/platforms/web/NavSegmentedChoiceBase.web.d.ts +112 -0
- package/dist/components/core/Nav-SegmentedChoice-Base/platforms/web/NavSegmentedChoiceBase.web.js +421 -0
- package/dist/components/core/Nav-SegmentedChoice-Base/types.d.ts +54 -0
- package/dist/components/core/Nav-SegmentedChoice-Base/types.js +22 -0
- package/dist/components/core/Nav-TabBar-Base/examples/BasicUsage.d.ts +1 -0
- package/dist/components/core/Nav-TabBar-Base/examples/BasicUsage.js +4 -0
- package/dist/components/core/Nav-TabBar-Base/index.d.ts +14 -0
- package/dist/components/core/Nav-TabBar-Base/index.js +18 -0
- package/dist/components/core/Nav-TabBar-Base/platforms/web/NavTabBarBase.web.d.ts +82 -0
- package/dist/components/core/Nav-TabBar-Base/platforms/web/NavTabBarBase.web.js +372 -0
- package/dist/components/core/Nav-TabBar-Base/types.d.ts +38 -0
- package/dist/components/core/Nav-TabBar-Base/types.js +17 -0
- package/dist/components/core/Progress-Bar-Base/index.d.ts +7 -0
- package/dist/components/core/Progress-Bar-Base/index.js +6 -0
- package/dist/components/core/Progress-Bar-Base/platforms/web/ProgressBarBase.web.d.ts +24 -0
- package/dist/components/core/Progress-Bar-Base/platforms/web/ProgressBarBase.web.js +121 -0
- package/dist/components/core/Progress-Bar-Base/types.d.ts +44 -0
- package/dist/components/core/Progress-Bar-Base/types.js +23 -0
- package/dist/components/core/Progress-Indicator-Connector-Base/index.d.ts +23 -0
- package/dist/components/core/Progress-Indicator-Connector-Base/index.js +32 -0
- package/dist/components/core/Progress-Indicator-Connector-Base/platforms/web/ProgressIndicatorConnectorBase.web.d.ts +61 -0
- package/dist/components/core/Progress-Indicator-Connector-Base/platforms/web/ProgressIndicatorConnectorBase.web.js +128 -0
- package/dist/components/core/Progress-Indicator-Connector-Base/types.d.ts +64 -0
- package/dist/components/core/Progress-Indicator-Connector-Base/types.js +26 -0
- package/dist/components/core/Progress-Indicator-Label-Base/index.d.ts +22 -0
- package/dist/components/core/Progress-Indicator-Label-Base/index.js +29 -0
- package/dist/components/core/Progress-Indicator-Label-Base/platforms/web/ProgressIndicatorLabelBase.web.d.ts +71 -0
- package/dist/components/core/Progress-Indicator-Label-Base/platforms/web/ProgressIndicatorLabelBase.web.js +160 -0
- package/dist/components/core/Progress-Indicator-Label-Base/types.d.ts +61 -0
- package/dist/components/core/Progress-Indicator-Label-Base/types.js +18 -0
- package/dist/components/core/Progress-Indicator-Node-Base/index.d.ts +23 -0
- package/dist/components/core/Progress-Indicator-Node-Base/index.js +33 -0
- package/dist/components/core/Progress-Indicator-Node-Base/platforms/web/ProgressIndicatorNodeBase.web.d.ts +85 -0
- package/dist/components/core/Progress-Indicator-Node-Base/platforms/web/ProgressIndicatorNodeBase.web.js +206 -0
- package/dist/components/core/Progress-Indicator-Node-Base/types.d.ts +141 -0
- package/dist/components/core/Progress-Indicator-Node-Base/types.js +46 -0
- package/dist/components/core/Progress-Pagination-Base/index.d.ts +26 -0
- package/dist/components/core/Progress-Pagination-Base/index.js +37 -0
- package/dist/components/core/Progress-Pagination-Base/platforms/web/ProgressPaginationBase.web.d.ts +86 -0
- package/dist/components/core/Progress-Pagination-Base/platforms/web/ProgressPaginationBase.web.js +256 -0
- package/dist/components/core/Progress-Pagination-Base/types.d.ts +97 -0
- package/dist/components/core/Progress-Pagination-Base/types.js +57 -0
- package/dist/components/core/Progress-Stepper-Base/index.d.ts +26 -0
- package/dist/components/core/Progress-Stepper-Base/index.js +40 -0
- package/dist/components/core/Progress-Stepper-Base/platforms/web/ProgressStepperBase.web.d.ts +93 -0
- package/dist/components/core/Progress-Stepper-Base/platforms/web/ProgressStepperBase.web.js +247 -0
- package/dist/components/core/Progress-Stepper-Base/types.d.ts +138 -0
- package/dist/components/core/Progress-Stepper-Base/types.js +98 -0
- package/dist/components/core/Progress-Stepper-Detailed/index.d.ts +27 -0
- package/dist/components/core/Progress-Stepper-Detailed/index.js +41 -0
- package/dist/components/core/Progress-Stepper-Detailed/platforms/web/ProgressStepperDetailed.web.d.ts +97 -0
- package/dist/components/core/Progress-Stepper-Detailed/platforms/web/ProgressStepperDetailed.web.js +290 -0
- package/dist/components/core/Progress-Stepper-Detailed/types.d.ts +152 -0
- package/dist/components/core/Progress-Stepper-Detailed/types.js +102 -0
- package/dist/composition/BlendComposition.d.ts +39 -0
- package/dist/composition/BlendComposition.js +15 -0
- package/dist/composition/BlendCompositionParser.d.ts +63 -0
- package/dist/composition/BlendCompositionParser.js +185 -0
- package/dist/composition/OpacityComposition.d.ts +52 -0
- package/dist/composition/OpacityComposition.js +14 -0
- package/dist/composition/OpacityCompositionParser.d.ts +82 -0
- package/dist/composition/OpacityCompositionParser.js +267 -0
- package/dist/composition/index.d.ts +10 -0
- package/dist/composition/index.js +13 -0
- package/dist/config/ConfigLoader.d.ts +71 -0
- package/dist/config/ConfigLoader.js +140 -0
- package/dist/config/defineConfig.d.ts +66 -0
- package/dist/config/defineConfig.js +35 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/config/index.js +11 -0
- package/dist/config/scopedTsRequire.d.ts +45 -0
- package/dist/config/scopedTsRequire.js +50 -0
- package/dist/constants/BaselineGrid.d.ts +31 -0
- package/dist/constants/BaselineGrid.js +39 -0
- package/dist/constants/SpacingTokens.d.ts +45 -0
- package/dist/constants/SpacingTokens.js +56 -0
- package/dist/constants/StrategicFlexibilityTokens.d.ts +121 -0
- package/dist/constants/StrategicFlexibilityTokens.js +93 -0
- package/dist/figma/ComponentAnalysis.d.ts +233 -0
- package/dist/figma/ComponentAnalysis.js +15 -0
- package/dist/figma/ComponentAnalysisGenerator.d.ts +79 -0
- package/dist/figma/ComponentAnalysisGenerator.js +391 -0
- package/dist/figma/ConsoleMCPClient.d.ts +147 -0
- package/dist/figma/ConsoleMCPClient.js +12 -0
- package/dist/figma/ConsoleMCPClientImpl.d.ts +159 -0
- package/dist/figma/ConsoleMCPClientImpl.js +918 -0
- package/dist/figma/DesignExtractor.d.ts +971 -0
- package/dist/figma/DesignExtractor.js +2838 -0
- package/dist/figma/TokenSyncWorkflow.d.ts +277 -0
- package/dist/figma/TokenSyncWorkflow.js +678 -0
- package/dist/figma/TokenTranslator.d.ts +261 -0
- package/dist/figma/TokenTranslator.js +713 -0
- package/dist/figma/VariantAnalyzer.d.ts +233 -0
- package/dist/figma/VariantAnalyzer.js +505 -0
- package/dist/figma/error-reporting.d.ts +89 -0
- package/dist/figma/error-reporting.js +189 -0
- package/dist/figma/index.d.ts +26 -0
- package/dist/figma/index.js +37 -0
- package/dist/figma/portCleanup.d.ts +21 -0
- package/dist/figma/portCleanup.js +76 -0
- package/dist/figma/preflight.d.ts +34 -0
- package/dist/figma/preflight.js +105 -0
- package/dist/generators/BlendUtilityGenerator.d.ts +80 -0
- package/dist/generators/BlendUtilityGenerator.js +788 -0
- package/dist/generators/BlendValueGenerator.d.ts +52 -0
- package/dist/generators/BlendValueGenerator.js +159 -0
- package/dist/generators/DTCGFormatGenerator.d.ts +332 -0
- package/dist/generators/DTCGFormatGenerator.js +1224 -0
- package/dist/generators/DTCGGeneratorConfig.d.ts +41 -0
- package/dist/generators/DTCGGeneratorConfig.js +29 -0
- package/dist/generators/ModeResolvedTokens.d.ts +53 -0
- package/dist/generators/ModeResolvedTokens.js +14 -0
- package/dist/generators/ResponsiveGridGenerator.d.ts +64 -0
- package/dist/generators/ResponsiveGridGenerator.js +234 -0
- package/dist/generators/TokenFileGenerator.d.ts +401 -0
- package/dist/generators/TokenFileGenerator.js +1666 -0
- package/dist/generators/generateTokenFiles.d.ts +24 -0
- package/dist/generators/generateTokenFiles.js +343 -0
- package/dist/generators/generateTokenIndex.d.ts +47 -0
- package/dist/generators/generateTokenIndex.js +226 -0
- package/dist/generators/oklch/OklchExportUtils.d.ts +34 -0
- package/dist/generators/oklch/OklchExportUtils.js +48 -0
- package/dist/generators/oklch/OklchTokenIndexMetadata.d.ts +23 -0
- package/dist/generators/oklch/OklchTokenIndexMetadata.js +21 -0
- package/dist/generators/transformers/FigmaTransformer.d.ts +263 -0
- package/dist/generators/transformers/FigmaTransformer.js +681 -0
- package/dist/generators/transformers/ITokenTransformer.d.ts +51 -0
- package/dist/generators/transformers/ITokenTransformer.js +13 -0
- package/dist/generators/transformers/TransformerRegistry.d.ts +33 -0
- package/dist/generators/transformers/TransformerRegistry.js +59 -0
- package/dist/generators/transformers/index.d.ts +39 -0
- package/dist/generators/transformers/index.js +45 -0
- package/dist/generators/types/DTCGTypes.d.ts +101 -0
- package/dist/generators/types/DTCGTypes.js +12 -0
- package/dist/integration/BuildErrorHandler.d.ts +140 -0
- package/dist/integration/BuildErrorHandler.js +277 -0
- package/dist/integration/BuildSystemInterface.d.ts +107 -0
- package/dist/integration/BuildSystemInterface.js +205 -0
- package/dist/integration/PlatformFileSelector.d.ts +84 -0
- package/dist/integration/PlatformFileSelector.js +215 -0
- package/dist/integration/RegistryCoordinator.d.ts +133 -0
- package/dist/integration/RegistryCoordinator.js +298 -0
- package/dist/integration/TranslationCoordinator.d.ts +118 -0
- package/dist/integration/TranslationCoordinator.js +352 -0
- package/dist/integration/TreeShakingOptimizer.d.ts +111 -0
- package/dist/integration/TreeShakingOptimizer.js +224 -0
- package/dist/integration/ValidationCoordinator.d.ts +268 -0
- package/dist/integration/ValidationCoordinator.js +567 -0
- package/dist/integration/index.d.ts +21 -0
- package/dist/integration/index.js +28 -0
- package/dist/ios/DesignTokens.ios.swift +697 -0
- package/dist/mcp/application-mcp.js +19434 -0
- package/dist/mcp/docs-mcp.js +16895 -0
- package/dist/mcp/product-mcp.js +24828 -0
- package/dist/naming/NamingConventionManager.d.ts +94 -0
- package/dist/naming/NamingConventionManager.js +193 -0
- package/dist/naming/PlatformNamingRules.d.ts +62 -0
- package/dist/naming/PlatformNamingRules.js +174 -0
- package/dist/naming/index.d.ts +9 -0
- package/dist/naming/index.js +18 -0
- package/dist/performance/CachingStrategy.d.ts +131 -0
- package/dist/performance/CachingStrategy.js +348 -0
- package/dist/performance/FileGenerationOptimizer.d.ts +91 -0
- package/dist/performance/FileGenerationOptimizer.js +201 -0
- package/dist/performance/PerformanceMonitor.d.ts +79 -0
- package/dist/performance/PerformanceMonitor.js +142 -0
- package/dist/performance/PerformanceOptimizer.d.ts +106 -0
- package/dist/performance/PerformanceOptimizer.js +241 -0
- package/dist/performance/index.d.ts +14 -0
- package/dist/performance/index.js +17 -0
- package/dist/providers/AndroidFileOrganizer.d.ts +56 -0
- package/dist/providers/AndroidFileOrganizer.js +225 -0
- package/dist/providers/AndroidFormatGenerator.d.ts +151 -0
- package/dist/providers/AndroidFormatGenerator.js +673 -0
- package/dist/providers/AndroidUnitConverter.d.ts +54 -0
- package/dist/providers/AndroidUnitConverter.js +151 -0
- package/dist/providers/FormatProvider.d.ts +103 -0
- package/dist/providers/FormatProvider.js +67 -0
- package/dist/providers/PathProvider.d.ts +114 -0
- package/dist/providers/PathProvider.js +64 -0
- package/dist/providers/UnitProvider.d.ts +65 -0
- package/dist/providers/UnitProvider.js +46 -0
- package/dist/providers/WebFileOrganizer.d.ts +35 -0
- package/dist/providers/WebFileOrganizer.js +113 -0
- package/dist/providers/WebFormatGenerator.d.ts +146 -0
- package/dist/providers/WebFormatGenerator.js +522 -0
- package/dist/providers/WebUnitConverter.d.ts +29 -0
- package/dist/providers/WebUnitConverter.js +99 -0
- package/dist/providers/iOSFileOrganizer.d.ts +42 -0
- package/dist/providers/iOSFileOrganizer.js +148 -0
- package/dist/providers/iOSFormatGenerator.d.ts +130 -0
- package/dist/providers/iOSFormatGenerator.js +512 -0
- package/dist/providers/iOSUnitConverter.d.ts +35 -0
- package/dist/providers/iOSUnitConverter.js +108 -0
- package/dist/providers/index.d.ts +14 -0
- package/dist/providers/index.js +35 -0
- package/dist/registries/ComponentTokenRegistry.d.ts +176 -0
- package/dist/registries/ComponentTokenRegistry.js +222 -0
- package/dist/registries/IRegistry.d.ts +166 -0
- package/dist/registries/IRegistry.js +3 -0
- package/dist/registries/PrimitiveTokenRegistry.d.ts +83 -0
- package/dist/registries/PrimitiveTokenRegistry.js +158 -0
- package/dist/registries/SemanticTokenRegistry.d.ts +92 -0
- package/dist/registries/SemanticTokenRegistry.js +188 -0
- package/dist/resolvers/AndroidColorResolver.d.ts +111 -0
- package/dist/resolvers/AndroidColorResolver.js +255 -0
- package/dist/resolvers/ModeThemeResolver.d.ts +82 -0
- package/dist/resolvers/ModeThemeResolver.js +113 -0
- package/dist/resolvers/SemanticOverrideResolver.d.ts +59 -0
- package/dist/resolvers/SemanticOverrideResolver.js +124 -0
- package/dist/resolvers/SemanticValueResolver.d.ts +20 -0
- package/dist/resolvers/SemanticValueResolver.js +122 -0
- package/dist/resolvers/WebColorResolver.d.ts +63 -0
- package/dist/resolvers/WebColorResolver.js +181 -0
- package/dist/resolvers/iOSColorResolver.d.ts +67 -0
- package/dist/resolvers/iOSColorResolver.js +175 -0
- package/dist/resolvers/index.d.ts +11 -0
- package/dist/resolvers/index.js +18 -0
- package/dist/security/AIAgentRestrictions.d.ts +115 -0
- package/dist/security/AIAgentRestrictions.js +185 -0
- package/dist/security/ContaminationAuditor.d.ts +96 -0
- package/dist/security/ContaminationAuditor.js +293 -0
- package/dist/security/ContaminationPrevention.d.ts +73 -0
- package/dist/security/ContaminationPrevention.js +222 -0
- package/dist/security/DocumentationGuard.d.ts +76 -0
- package/dist/security/DocumentationGuard.js +199 -0
- package/dist/security/FlexibilityTokenGuard.d.ts +136 -0
- package/dist/security/FlexibilityTokenGuard.js +187 -0
- package/dist/security/HumanApprovalWorkflow.d.ts +129 -0
- package/dist/security/HumanApprovalWorkflow.js +213 -0
- package/dist/security/index.d.ts +19 -0
- package/dist/security/index.js +23 -0
- package/dist/testing/index.d.ts +74 -0
- package/dist/testing/index.js +142 -0
- package/dist/testing/jest-preset.d.ts +27 -0
- package/dist/testing/jest-preset.js +94 -0
- package/dist/testing/style-mock.d.ts +1 -0
- package/dist/testing/style-mock.js +9 -0
- package/dist/testing/validators.d.ts +10 -0
- package/dist/testing/validators.js +26 -0
- package/dist/themes/ResolvedThemeSet.d.ts +21 -0
- package/dist/themes/ResolvedThemeSet.js +8 -0
- package/dist/themes/ThemeRegistry.d.ts +52 -0
- package/dist/themes/ThemeRegistry.js +77 -0
- package/dist/tokens/BlendTokens.d.ts +45 -0
- package/dist/tokens/BlendTokens.js +127 -0
- package/dist/tokens/BlurTokens.d.ts +28 -0
- package/dist/tokens/BlurTokens.js +153 -0
- package/dist/tokens/BorderWidthTokens.d.ts +29 -0
- package/dist/tokens/BorderWidthTokens.js +97 -0
- package/dist/tokens/BreakpointTokens.d.ts +29 -0
- package/dist/tokens/BreakpointTokens.js +97 -0
- package/dist/tokens/ColorTokens.d.ts +270 -0
- package/dist/tokens/ColorTokens.js +2085 -0
- package/dist/tokens/DensityTokens.d.ts +36 -0
- package/dist/tokens/DensityTokens.js +113 -0
- package/dist/tokens/DurationTokens.d.ts +47 -0
- package/dist/tokens/DurationTokens.js +108 -0
- package/dist/tokens/EasingTokens.d.ts +47 -0
- package/dist/tokens/EasingTokens.js +159 -0
- package/dist/tokens/FontFamilyTokens.d.ts +24 -0
- package/dist/tokens/FontFamilyTokens.js +92 -0
- package/dist/tokens/FontSizeTokens.d.ts +33 -0
- package/dist/tokens/FontSizeTokens.js +185 -0
- package/dist/tokens/FontWeightTokens.d.ts +29 -0
- package/dist/tokens/FontWeightTokens.js +157 -0
- package/dist/tokens/GlowOpacityTokens.d.ts +41 -0
- package/dist/tokens/GlowOpacityTokens.js +109 -0
- package/dist/tokens/LetterSpacingTokens.d.ts +29 -0
- package/dist/tokens/LetterSpacingTokens.js +109 -0
- package/dist/tokens/LineHeightTokens.d.ts +34 -0
- package/dist/tokens/LineHeightTokens.js +189 -0
- package/dist/tokens/OpacityTokens.d.ts +30 -0
- package/dist/tokens/OpacityTokens.js +219 -0
- package/dist/tokens/RadiusTokens.d.ts +37 -0
- package/dist/tokens/RadiusTokens.js +223 -0
- package/dist/tokens/ScaleTokens.d.ts +62 -0
- package/dist/tokens/ScaleTokens.js +161 -0
- package/dist/tokens/ShadowOffsetTokens.d.ts +69 -0
- package/dist/tokens/ShadowOffsetTokens.js +264 -0
- package/dist/tokens/ShadowOpacityTokens.d.ts +22 -0
- package/dist/tokens/ShadowOpacityTokens.js +112 -0
- package/dist/tokens/SizingTokens.d.ts +35 -0
- package/dist/tokens/SizingTokens.js +220 -0
- package/dist/tokens/SpacingTokens.d.ts +29 -0
- package/dist/tokens/SpacingTokens.js +239 -0
- package/dist/tokens/TapAreaTokens.d.ts +38 -0
- package/dist/tokens/TapAreaTokens.js +115 -0
- package/dist/tokens/color/channels/chroma/chromatic.d.ts +61 -0
- package/dist/tokens/color/channels/chroma/chromatic.js +64 -0
- package/dist/tokens/color/channels/chroma/neutral.d.ts +33 -0
- package/dist/tokens/color/channels/chroma/neutral.js +36 -0
- package/dist/tokens/color/channels/hues.d.ts +27 -0
- package/dist/tokens/color/channels/hues.js +29 -0
- package/dist/tokens/color/channels/index.d.ts +11 -0
- package/dist/tokens/color/channels/index.js +36 -0
- package/dist/tokens/color/channels/lightness/chromatic.d.ts +62 -0
- package/dist/tokens/color/channels/lightness/chromatic.js +65 -0
- package/dist/tokens/color/channels/lightness/neutral.d.ts +34 -0
- package/dist/tokens/color/channels/lightness/neutral.js +37 -0
- package/dist/tokens/color/index.d.ts +16 -0
- package/dist/tokens/color/index.js +47 -0
- package/dist/tokens/color/primitives/chromatic.d.ts +24 -0
- package/dist/tokens/color/primitives/chromatic.js +42 -0
- package/dist/tokens/color/primitives/neutral.d.ts +12 -0
- package/dist/tokens/color/primitives/neutral.js +37 -0
- package/dist/tokens/component/progress.d.ts +101 -0
- package/dist/tokens/component/progress.js +145 -0
- package/dist/tokens/index.d.ts +167 -0
- package/dist/tokens/index.js +341 -0
- package/dist/tokens/semantic/AccessibilityTokens.d.ts +112 -0
- package/dist/tokens/semantic/AccessibilityTokens.js +175 -0
- package/dist/tokens/semantic/BlendTokens.d.ts +112 -0
- package/dist/tokens/semantic/BlendTokens.js +191 -0
- package/dist/tokens/semantic/BorderWidthTokens.d.ts +156 -0
- package/dist/tokens/semantic/BorderWidthTokens.js +147 -0
- package/dist/tokens/semantic/ColorTokens.d.ts +157 -0
- package/dist/tokens/semantic/ColorTokens.js +791 -0
- package/dist/tokens/semantic/ElevationTokens.d.ts +98 -0
- package/dist/tokens/semantic/ElevationTokens.js +158 -0
- package/dist/tokens/semantic/GridSpacingTokens.d.ts +36 -0
- package/dist/tokens/semantic/GridSpacingTokens.js +139 -0
- package/dist/tokens/semantic/IconTokens.d.ts +70 -0
- package/dist/tokens/semantic/IconTokens.js +309 -0
- package/dist/tokens/semantic/LayeringTokens.d.ts +135 -0
- package/dist/tokens/semantic/LayeringTokens.js +163 -0
- package/dist/tokens/semantic/MotionTokens.d.ts +74 -0
- package/dist/tokens/semantic/MotionTokens.js +131 -0
- package/dist/tokens/semantic/OpacityTokens.d.ts +40 -0
- package/dist/tokens/semantic/OpacityTokens.js +87 -0
- package/dist/tokens/semantic/RadiusTokens.d.ts +233 -0
- package/dist/tokens/semantic/RadiusTokens.js +224 -0
- package/dist/tokens/semantic/ShadowTokens.d.ts +55 -0
- package/dist/tokens/semantic/ShadowTokens.js +409 -0
- package/dist/tokens/semantic/SpacingTokens.d.ts +397 -0
- package/dist/tokens/semantic/SpacingTokens.js +243 -0
- package/dist/tokens/semantic/StyleTokens.d.ts +19 -0
- package/dist/tokens/semantic/StyleTokens.js +25 -0
- package/dist/tokens/semantic/TypographyTokens.d.ts +32 -0
- package/dist/tokens/semantic/TypographyTokens.js +376 -0
- package/dist/tokens/semantic/ZIndexTokens.d.ts +61 -0
- package/dist/tokens/semantic/ZIndexTokens.js +107 -0
- package/dist/tokens/semantic/index.d.ts +94 -0
- package/dist/tokens/semantic/index.js +547 -0
- package/dist/tokens/themes/dark/SemanticOverrides.d.ts +16 -0
- package/dist/tokens/themes/dark/SemanticOverrides.js +149 -0
- package/dist/tokens/themes/dark-wcag/SemanticOverrides.d.ts +14 -0
- package/dist/tokens/themes/dark-wcag/SemanticOverrides.js +21 -0
- package/dist/tokens/themes/types.d.ts +22 -0
- package/dist/tokens/themes/types.js +10 -0
- package/dist/tokens/themes/wcag/SemanticOverrides.d.ts +12 -0
- package/dist/tokens/themes/wcag/SemanticOverrides.js +26 -0
- package/dist/tools/ThemeFileGenerator.d.ts +16 -0
- package/dist/tools/ThemeFileGenerator.js +103 -0
- package/dist/tools/integrity/DiskFreshGenerator.d.ts +19 -0
- package/dist/tools/integrity/DiskFreshGenerator.js +68 -0
- package/dist/tools/integrity/GenerationIntegrityCheck.d.ts +31 -0
- package/dist/tools/integrity/GenerationIntegrityCheck.js +137 -0
- package/dist/tools/integrity/Invariants.d.ts +82 -0
- package/dist/tools/integrity/Invariants.js +231 -0
- package/dist/tools/integrity/Normalizer.d.ts +28 -0
- package/dist/tools/integrity/Normalizer.js +122 -0
- package/dist/tools/integrity/ParityNormalizationRules.d.ts +55 -0
- package/dist/tools/integrity/ParityNormalizationRules.js +163 -0
- package/dist/tools/integrity/ParityOrchestrator.d.ts +97 -0
- package/dist/tools/integrity/ParityOrchestrator.js +234 -0
- package/dist/tools/integrity/SemanticComparator.d.ts +24 -0
- package/dist/tools/integrity/SemanticComparator.js +108 -0
- package/dist/tools/integrity/cli/run-audit.d.ts +21 -0
- package/dist/tools/integrity/cli/run-audit.js +178 -0
- package/dist/tools/integrity/inventory.d.ts +26 -0
- package/dist/tools/integrity/inventory.js +48 -0
- package/dist/tools/integrity/manifest.d.ts +44 -0
- package/dist/tools/integrity/manifest.js +54 -0
- package/dist/tools/integrity/types/index.d.ts +146 -0
- package/dist/tools/integrity/types/index.js +21 -0
- package/dist/tools/release/cli/ReleasePipeline.d.ts +28 -0
- package/dist/tools/release/cli/ReleasePipeline.js +184 -0
- package/dist/tools/release/cli/release-tool.d.ts +11 -0
- package/dist/tools/release/cli/release-tool.js +98 -0
- package/dist/tools/release/pipeline/ChangeClassifier.d.ts +13 -0
- package/dist/tools/release/pipeline/ChangeClassifier.js +53 -0
- package/dist/tools/release/pipeline/ChangeExtractor.d.ts +16 -0
- package/dist/tools/release/pipeline/ChangeExtractor.js +80 -0
- package/dist/tools/release/pipeline/NotesRenderer.d.ts +15 -0
- package/dist/tools/release/pipeline/NotesRenderer.js +62 -0
- package/dist/tools/release/pipeline/SummaryScanner.d.ts +16 -0
- package/dist/tools/release/pipeline/SummaryScanner.js +94 -0
- package/dist/tools/release/pipeline/TagResolver.d.ts +15 -0
- package/dist/tools/release/pipeline/TagResolver.js +37 -0
- package/dist/tools/release/pipeline/VersionCalculator.d.ts +34 -0
- package/dist/tools/release/pipeline/VersionCalculator.js +325 -0
- package/dist/tools/release/publishers/GitHubPublisher.d.ts +33 -0
- package/dist/tools/release/publishers/GitHubPublisher.js +239 -0
- package/dist/tools/release/publishers/NpmPublisher.d.ts +49 -0
- package/dist/tools/release/publishers/NpmPublisher.js +226 -0
- package/dist/tools/release/types/index.d.ts +239 -0
- package/dist/tools/release/types/index.js +11 -0
- package/dist/tools/release/validators/SemanticVersionValidator.d.ts +18 -0
- package/dist/tools/release/validators/SemanticVersionValidator.js +56 -0
- package/dist/types/ComponentTypes.d.ts +70 -0
- package/dist/types/ComponentTypes.js +12 -0
- package/dist/types/PrimitiveToken.d.ts +105 -0
- package/dist/types/PrimitiveToken.js +38 -0
- package/dist/types/SemanticToken.d.ts +79 -0
- package/dist/types/SemanticToken.js +27 -0
- package/dist/types/TranslationOutput.d.ts +80 -0
- package/dist/types/TranslationOutput.js +9 -0
- package/dist/types/ValidationResult.d.ts +58 -0
- package/dist/types/ValidationResult.js +9 -0
- package/dist/types/generated/TokenTypes.d.ts +48 -0
- package/dist/types/generated/TokenTypes.js +35 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.js +14 -0
- package/dist/validators/BaselineGridValidator.d.ts +55 -0
- package/dist/validators/BaselineGridValidator.js +96 -0
- package/dist/validators/CompositionPatternValidator.d.ts +75 -0
- package/dist/validators/CompositionPatternValidator.js +178 -0
- package/dist/validators/CrossPlatformConsistencyValidator.d.ts +112 -0
- package/dist/validators/CrossPlatformConsistencyValidator.js +313 -0
- package/dist/validators/ErrorValidator.d.ts +161 -0
- package/dist/validators/ErrorValidator.js +652 -0
- package/dist/validators/IValidator.d.ts +260 -0
- package/dist/validators/IValidator.js +43 -0
- package/dist/validators/MathematicalRelationshipParser.d.ts +112 -0
- package/dist/validators/MathematicalRelationshipParser.js +325 -0
- package/dist/validators/ModeParity.d.ts +37 -0
- package/dist/validators/ModeParity.js +133 -0
- package/dist/validators/PassValidator.d.ts +100 -0
- package/dist/validators/PassValidator.js +400 -0
- package/dist/validators/PlatformConstraintHandler.d.ts +103 -0
- package/dist/validators/PlatformConstraintHandler.js +309 -0
- package/dist/validators/PrimitiveReferenceValidator.d.ts +68 -0
- package/dist/validators/PrimitiveReferenceValidator.js +244 -0
- package/dist/validators/SemanticTokenValidator.d.ts +120 -0
- package/dist/validators/SemanticTokenValidator.js +382 -0
- package/dist/validators/StemmaComponentNamingValidator.d.ts +145 -0
- package/dist/validators/StemmaComponentNamingValidator.js +392 -0
- package/dist/validators/StemmaErrorGuidanceSystem.d.ts +292 -0
- package/dist/validators/StemmaErrorGuidanceSystem.js +1287 -0
- package/dist/validators/StemmaPropertyAccessibilityValidator.d.ts +250 -0
- package/dist/validators/StemmaPropertyAccessibilityValidator.js +642 -0
- package/dist/validators/StemmaTokenUsageValidator.d.ts +135 -0
- package/dist/validators/StemmaTokenUsageValidator.js +503 -0
- package/dist/validators/SyntaxValidator.d.ts +116 -0
- package/dist/validators/SyntaxValidator.js +369 -0
- package/dist/validators/ThreeTierValidator.d.ts +289 -0
- package/dist/validators/ThreeTierValidator.js +533 -0
- package/dist/validators/ToleranceCalculator.d.ts +104 -0
- package/dist/validators/ToleranceCalculator.js +222 -0
- package/dist/validators/ValidationReasoning.d.ts +104 -0
- package/dist/validators/ValidationReasoning.js +307 -0
- package/dist/validators/WCAGValidator.d.ts +108 -0
- package/dist/validators/WCAGValidator.js +188 -0
- package/dist/validators/WarningValidator.d.ts +125 -0
- package/dist/validators/WarningValidator.js +383 -0
- package/dist/validators/buildValidation.d.ts +34 -0
- package/dist/validators/buildValidation.js +135 -0
- package/dist/validators/index.d.ts +32 -0
- package/dist/validators/index.js +105 -0
- package/dist/web/DesignTokens.web.css +929 -0
- package/dist/workflows/ConsistencyValidator.d.ts +91 -0
- package/dist/workflows/ConsistencyValidator.js +272 -0
- package/dist/workflows/TokenGenerationWorkflow.d.ts +129 -0
- package/dist/workflows/TokenGenerationWorkflow.js +316 -0
- package/dist/workflows/ValidationPipeline.d.ts +103 -0
- package/dist/workflows/ValidationPipeline.js +213 -0
- package/dist/workflows/WorkflowErrorHandler.d.ts +141 -0
- package/dist/workflows/WorkflowErrorHandler.js +357 -0
- package/experience-patterns/README.md +160 -0
- package/experience-patterns/content-preview.yaml +48 -0
- package/experience-patterns/dashboard.yaml +97 -0
- package/experience-patterns/empty-state.yaml +50 -0
- package/experience-patterns/multi-section-form.yaml +105 -0
- package/experience-patterns/notification-list.yaml +109 -0
- package/experience-patterns/onboarding.yaml +197 -0
- package/experience-patterns/settings.yaml +98 -0
- package/experience-patterns/simple-form.yaml +41 -0
- package/experience-patterns/view-edit-screen.yaml +125 -0
- package/family-guidance/README.md +115 -0
- package/family-guidance/avatars.yaml +63 -0
- package/family-guidance/badges.yaml +76 -0
- package/family-guidance/button.yaml +108 -0
- package/family-guidance/chips.yaml +82 -0
- package/family-guidance/container.yaml +69 -0
- package/family-guidance/form-inputs.yaml +104 -0
- package/family-guidance/icons.yaml +87 -0
- package/family-guidance/navigation.yaml +96 -0
- package/family-guidance/progress.yaml +85 -0
- package/family-registry.yaml +49 -0
- package/governance/AI-Collaboration-Framework.md +305 -0
- package/governance/BUILD-SYSTEM-SETUP.md +233 -0
- package/governance/Component-Development-Guide.md +1876 -0
- package/governance/Component-Development-Standards.md +1189 -0
- package/governance/Component-Family-Avatar.md +290 -0
- package/governance/Component-Family-Badge.md +479 -0
- package/governance/Component-Family-Button.md +671 -0
- package/governance/Component-Family-Chip.md +431 -0
- package/governance/Component-Family-Container.md +671 -0
- package/governance/Component-Family-Data-Display.md +149 -0
- package/governance/Component-Family-Divider.md +138 -0
- package/governance/Component-Family-Form-Inputs.md +1365 -0
- package/governance/Component-Family-Icon.md +364 -0
- package/governance/Component-Family-Loading.md +143 -0
- package/governance/Component-Family-Modal.md +151 -0
- package/governance/Component-Family-Navigation.md +266 -0
- package/governance/Component-Family-Progress.md +488 -0
- package/governance/Component-Inheritance-Structures.md +687 -0
- package/governance/Component-MCP-Document-Template.md +722 -0
- package/governance/Component-Meta-Data-Shapes-Governance.md +120 -0
- package/governance/Component-Primitive-vs-Semantic-Philosophy.md +404 -0
- package/governance/Component-Quick-Reference.md +304 -0
- package/governance/Component-Readiness-Status.md +660 -0
- package/governance/Component-Schema-Format.md +379 -0
- package/governance/Component-Templates.md +1118 -0
- package/governance/Contract-System-Reference.md +255 -0
- package/governance/DTCG-Integration-Guide.md +573 -0
- package/governance/DesignerPunk-Integration-Guide.md +1005 -0
- package/governance/Figma-Workflow-Guide.md +479 -0
- package/governance/Layout-Specification-Vocabulary.md +550 -0
- package/governance/MCP-Evolution-Roadmap.md +228 -0
- package/governance/MCP-Integration-Guide.md +509 -0
- package/governance/MCP-Relationship-Model.md +363 -0
- package/governance/Platform-Resource-Map.md +70 -0
- package/governance/Process-Cross-Reference-Standards.md +665 -0
- package/governance/Process-Development-Workflow.md +310 -0
- package/governance/Process-File-Organization.md +693 -0
- package/governance/Process-Hook-Operations.md +1196 -0
- package/governance/Process-Integration-Methodology.md +142 -0
- package/governance/Process-Spec-Planning.md +2988 -0
- package/governance/Process-Task-Type-Definitions.md +378 -0
- package/governance/Product-Handoff-Protocol.md +258 -0
- package/governance/Product-Token-Governance.md +307 -0
- package/governance/Rosetta-System-Architecture.md +648 -0
- package/governance/Steering-Addressing-Conventions.md +105 -0
- package/governance/Test-Behavioral-Contract-Validation.md +638 -0
- package/governance/Test-Development-Standards.md +2094 -0
- package/governance/Test-Failure-Audit-Methodology.md +1475 -0
- package/governance/Token-Family-Accessibility.md +656 -0
- package/governance/Token-Family-Blend.md +503 -0
- package/governance/Token-Family-Blur.md +115 -0
- package/governance/Token-Family-Border.md +477 -0
- package/governance/Token-Family-Color.md +317 -0
- package/governance/Token-Family-Glow.md +473 -0
- package/governance/Token-Family-Layering.md +685 -0
- package/governance/Token-Family-Motion.md +690 -0
- package/governance/Token-Family-Opacity.md +578 -0
- package/governance/Token-Family-Radius.md +428 -0
- package/governance/Token-Family-Responsive.md +798 -0
- package/governance/Token-Family-Shadow.md +758 -0
- package/governance/Token-Family-Sizing.md +102 -0
- package/governance/Token-Family-Spacing.md +632 -0
- package/governance/Token-Family-Typography.md +598 -0
- package/governance/Token-Governance.md +658 -0
- package/governance/Token-Quick-Reference.md +382 -0
- package/governance/Token-Resolution-Patterns.md +537 -0
- package/governance/Token-Semantic-Structure.md +776 -0
- package/governance/Transformer-Development-Guide.md +490 -0
- package/governance/Web-Authoring-Standards.md +403 -0
- package/governance/a-vision-of-the-future.md +686 -0
- package/governance/browser-distribution-guide.md +580 -0
- package/governance/completion-documentation-guide.md +371 -0
- package/governance/component-mcp-query-guide.md +500 -0
- package/governance/component-meta-authoring-guide.md +235 -0
- package/governance/component-metadata-schema-reference.md +227 -0
- package/governance/cross-platform-vs-platform-specific-decision-framework.md +355 -0
- package/governance/platform-implementation-guidelines.md +818 -0
- package/governance/release-management-system.md +89 -0
- package/governance/rosetta-system-principles.md +593 -0
- package/governance/stemma-system-principles.md +900 -0
- package/governance/technology-stack.md +97 -0
- package/layout-templates/centered-content-page.yaml +26 -0
- package/layout-templates/full-width-page.yaml +24 -0
- package/layout-templates/multi-zone-page.yaml +56 -0
- package/layout-templates/sidebar-page.yaml +41 -0
- package/mcp-server/package.json +33 -0
- package/mcp-server/src/discovery-dry-run/__tests__/discovery-dry-run.test.ts +210 -0
- package/mcp-server/src/discovery-dry-run/discovery-dry-run.ts +224 -0
- package/mcp-server/src/id-guard/__tests__/backfill-doc-ids.test.ts +123 -0
- package/mcp-server/src/id-guard/__tests__/check-id-uniqueness.test.ts +138 -0
- package/mcp-server/src/id-guard/backfill-doc-ids.ts +180 -0
- package/mcp-server/src/id-guard/check-id-uniqueness.ts +165 -0
- package/mcp-server/src/id-guard/manifest-consistency.ts +77 -0
- package/mcp-server/src/index.ts +439 -0
- package/mcp-server/src/indexer/DocumentIndexer.ts +808 -0
- package/mcp-server/src/indexer/__tests__/DocumentIndexer.resolver.test.ts +298 -0
- package/mcp-server/src/indexer/__tests__/DocumentIndexer.test.ts +682 -0
- package/mcp-server/src/indexer/__tests__/conditional-filter.test.ts +367 -0
- package/mcp-server/src/indexer/__tests__/cross-ref-parser.test.ts +331 -0
- package/mcp-server/src/indexer/__tests__/frontmatter-parser.test.ts +192 -0
- package/mcp-server/src/indexer/__tests__/heading-parser.test.ts +227 -0
- package/mcp-server/src/indexer/__tests__/index-health.test.ts +393 -0
- package/mcp-server/src/indexer/__tests__/metadata-parser.test.ts +234 -0
- package/mcp-server/src/indexer/__tests__/section-parser.test.ts +494 -0
- package/mcp-server/src/indexer/conditional-filter.ts +282 -0
- package/mcp-server/src/indexer/cross-ref-parser.ts +65 -0
- package/mcp-server/src/indexer/frontmatter-parser.ts +192 -0
- package/mcp-server/src/indexer/heading-parser.ts +65 -0
- package/mcp-server/src/indexer/index-health.ts +228 -0
- package/mcp-server/src/indexer/metadata-parser.ts +81 -0
- package/mcp-server/src/indexer/section-parser.ts +296 -0
- package/mcp-server/src/legacy-path/__tests__/generate-manifest.test.ts +188 -0
- package/mcp-server/src/legacy-path/__tests__/reseed-integration.test.ts +113 -0
- package/mcp-server/src/legacy-path/generate-manifest.ts +214 -0
- package/mcp-server/src/legacy-path/index.ts +48 -0
- package/mcp-server/src/legacy-path/legacy-path-manifest.ts +160 -0
- package/mcp-server/src/models/CrossReference.ts +19 -0
- package/mcp-server/src/models/DocumentFull.ts +26 -0
- package/mcp-server/src/models/DocumentSummary.ts +53 -0
- package/mcp-server/src/models/DocumentationMap.ts +90 -0
- package/mcp-server/src/models/IndexHealth.ts +44 -0
- package/mcp-server/src/models/LegacyPathManifest.ts +37 -0
- package/mcp-server/src/models/MetadataValidation.ts +30 -0
- package/mcp-server/src/models/Section.ts +38 -0
- package/mcp-server/src/models/index.ts +14 -0
- package/mcp-server/src/query/QueryEngine.ts +860 -0
- package/mcp-server/src/query/__tests__/QueryEngine.test.ts +438 -0
- package/mcp-server/src/query/__tests__/find-docs-calibration.test.ts +406 -0
- package/mcp-server/src/query/__tests__/find-docs-rubric.test.ts +227 -0
- package/mcp-server/src/query/__tests__/stop-words.test.ts +40 -0
- package/mcp-server/src/query/stop-words.ts +74 -0
- package/mcp-server/src/relocation-integrity-gate/__tests__/relocation-integrity-gate.test.ts +236 -0
- package/mcp-server/src/relocation-integrity-gate/relocation-integrity-gate.ts +637 -0
- package/mcp-server/src/rules/workflow-rules.ts +105 -0
- package/mcp-server/src/staleness/StalenessGate.ts +112 -0
- package/mcp-server/src/staleness/__tests__/StalenessGate.test.ts +214 -0
- package/mcp-server/src/tools/__tests__/get-document-full.test.ts +256 -0
- package/mcp-server/src/tools/__tests__/get-document-summary.test.ts +273 -0
- package/mcp-server/src/tools/__tests__/get-documentation-map.test.ts +357 -0
- package/mcp-server/src/tools/__tests__/get-health-status.test.ts +223 -0
- package/mcp-server/src/tools/__tests__/get-index-health.test.ts +184 -0
- package/mcp-server/src/tools/__tests__/get-section.test.ts +457 -0
- package/mcp-server/src/tools/__tests__/list-cross-references.test.ts +279 -0
- package/mcp-server/src/tools/__tests__/rebuild-index.test.ts +214 -0
- package/mcp-server/src/tools/__tests__/validate-metadata.test.ts +296 -0
- package/mcp-server/src/tools/find-docs.ts +154 -0
- package/mcp-server/src/tools/get-document-full.ts +165 -0
- package/mcp-server/src/tools/get-document-summary.ts +198 -0
- package/mcp-server/src/tools/get-health-status.ts +137 -0
- package/mcp-server/src/tools/get-index-health.ts +100 -0
- package/mcp-server/src/tools/get-section.ts +308 -0
- package/mcp-server/src/tools/index.ts +106 -0
- package/mcp-server/src/tools/list-cross-references.ts +167 -0
- package/mcp-server/src/tools/rebuild-index.ts +101 -0
- package/mcp-server/src/tools/validate-metadata.ts +167 -0
- package/mcp-server/src/utils/__tests__/error-handler.test.ts +256 -0
- package/mcp-server/src/utils/__tests__/token-estimator.test.ts +87 -0
- package/mcp-server/src/utils/error-handler.ts +261 -0
- package/mcp-server/src/utils/token-estimator.ts +35 -0
- package/mcp-server/src/watcher/FileWatcher.ts +156 -0
- package/mcp-server/src/watcher/__tests__/FileWatcher.test.ts +293 -0
- package/mcp-server/src/watcher/index.ts +1 -0
- package/mcp-server/tsconfig.json +24 -0
- package/package.json +167 -0
- package/product-template/agents/README.md +73 -0
- package/product-template/agents/ada-prompt.md +83 -0
- package/product-template/agents/data-prompt.md +74 -0
- package/product-template/agents/kenya-prompt.md +74 -0
- package/product-template/agents/leonardo-prompt.md +99 -0
- package/product-template/agents/lina-prompt.md +61 -0
- package/product-template/agents/sparky-prompt.md +66 -0
- package/product-template/agents/stacy-prompt.md +51 -0
- package/product-template/agents/thurgood-prompt.md +64 -0
- package/src/TokenEngine.ts +628 -0
- package/src/__tests__/BuildSystemIntegration.test.ts +485 -0
- package/src/__tests__/ProductMCPIntegration.test.ts +204 -0
- package/src/__tests__/__mocks__/styleMock.js +18 -0
- package/src/__tests__/browser-distribution/build-error-handling.test.ts +143 -0
- package/src/__tests__/browser-distribution/bundle-loading.test.ts +353 -0
- package/src/__tests__/browser-distribution/bundler-resolution.test.ts +223 -0
- package/src/__tests__/browser-distribution/component-registration.test.ts +217 -0
- package/src/__tests__/browser-distribution/css-bundling.test.ts +231 -0
- package/src/__tests__/browser-distribution/demo-system.test.ts +588 -0
- package/src/__tests__/browser-distribution/mcp-format-compliance.property.test.ts +379 -0
- package/src/__tests__/browser-distribution/mcp-queryability.test.ts +342 -0
- package/src/__tests__/browser-distribution/minification-effectiveness.property.test.ts +188 -0
- package/src/__tests__/browser-distribution/registration-idempotency.property.test.ts +372 -0
- package/src/__tests__/browser-distribution/soft-ceiling-warning.test.ts +161 -0
- package/src/__tests__/browser-distribution/token-completeness.property.test.ts +412 -0
- package/src/__tests__/browser-distribution/token-loading.test.ts +344 -0
- package/src/__tests__/browser-distribution/umd-bundle-loading.test.ts +169 -0
- package/src/__tests__/examples/improved-test-example.test.ts +120 -0
- package/src/__tests__/expected-exports.json +66 -0
- package/src/__tests__/export-contracts.test.ts +83 -0
- package/src/__tests__/fixtures/acknowledged-differences.json +127 -0
- package/src/__tests__/fixtures/acknowledged-differences.schema.json +113 -0
- package/src/__tests__/fixtures/acknowledged-differences.types.ts +230 -0
- package/src/__tests__/fixtures/tokenFixtures.ts +248 -0
- package/src/__tests__/helpers/configModuleLoader.ts +20 -0
- package/src/__tests__/helpers/tsModuleLoader.ts +24 -0
- package/src/__tests__/helpers/web-component-test-utils.ts +39 -0
- package/src/__tests__/integration/BlendCrossPlatformConsistency.test.ts +505 -0
- package/src/__tests__/integration/BuildSystemCompatibility.test.ts +551 -0
- package/src/__tests__/integration/CrossPlatformConsistency.test.ts +855 -0
- package/src/__tests__/integration/EndToEndWorkflow.test.ts +601 -0
- package/src/__tests__/integration/ErrorHandling.test.ts +459 -0
- package/src/__tests__/integration/OpacityPlatformTranslation.test.ts +364 -0
- package/src/__tests__/integration/PerformanceValidation.test.ts +887 -0
- package/src/__tests__/integration/SemanticTokenGeneration.test.ts +451 -0
- package/src/__tests__/integration/Spec107-DesignLanguageContext.test.ts +123 -0
- package/src/__tests__/integration/TokenSystemIntegration.test.ts +890 -0
- package/src/__tests__/integration/ValidationPipeline.test.ts +404 -0
- package/src/__tests__/package-drift-validation.test.ts +249 -0
- package/src/__tests__/performance/GenerationPerformance.test.ts +409 -0
- package/src/__tests__/performance/OptimizationValidation.test.ts +509 -0
- package/src/__tests__/platform-parity/ProgressPlatformParity.test.ts +546 -0
- package/src/__tests__/spec073-opacity-architecture.test.ts +344 -0
- package/src/__tests__/stemma-system/behavioral-contract-validation.test.ts +467 -0
- package/src/__tests__/stemma-system/composition-compliance-validation.test.ts +162 -0
- package/src/__tests__/stemma-system/contract-catalog-name-validation.test.ts +156 -0
- package/src/__tests__/stemma-system/contract-existence-validation.test.ts +43 -0
- package/src/__tests__/stemma-system/contract-test-reporter.ts +269 -0
- package/src/__tests__/stemma-system/cross-platform-consistency.test.ts +564 -0
- package/src/__tests__/stemma-system/form-inputs-contracts.test.ts +503 -0
- package/src/__tests__/stemma-system/mcp-component-integration.test.ts +445 -0
- package/src/analytics/PrimitiveTokenFallbackTracker.ts +228 -0
- package/src/analytics/SemanticTokenUsageTracker.ts +193 -0
- package/src/analytics/StrategicFlexibilityTracker.ts +226 -0
- package/src/analytics/TokenUsageTracker.ts +177 -0
- package/src/analytics/UsagePatternAnalyzer.ts +177 -0
- package/src/analytics/__tests__/UsageTracking.test.ts +647 -0
- package/src/analytics/index.ts +42 -0
- package/src/assets/fonts/__tests__/androidFontLoadingValidation.test.ts +600 -0
- package/src/assets/fonts/__tests__/fontLoading.test.ts +341 -0
- package/src/assets/fonts/__tests__/iosFontConfiguration.test.ts +256 -0
- package/src/assets/fonts/__tests__/iosFontLoadingValidation.test.ts +465 -0
- package/src/assets/fonts/commit-mono/CommitMono-400-Italic.otf +0 -0
- package/src/assets/fonts/commit-mono/CommitMono-400-Regular.otf +0 -0
- package/src/assets/fonts/commit-mono/CommitMono-700-Italic.otf +0 -0
- package/src/assets/fonts/commit-mono/CommitMono-700-Regular.otf +0 -0
- package/src/assets/fonts/commit-mono/commit-mono.css +45 -0
- package/src/assets/fonts/commit-mono/custom-settings.json +1 -0
- package/src/assets/fonts/commit-mono/installation.txt +11 -0
- package/src/assets/fonts/commit-mono/license.txt +92 -0
- package/src/assets/fonts/figtree/Figtree-Italic-VariableFont_wght.ttf +0 -0
- package/src/assets/fonts/figtree/Figtree-VariableFont_wght.ttf +0 -0
- package/src/assets/fonts/figtree/OFL.txt +93 -0
- package/src/assets/fonts/figtree/README.txt +77 -0
- package/src/assets/fonts/figtree/figtree.css +27 -0
- package/src/assets/fonts/figtree/static/Figtree-Black.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-BlackItalic.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-Bold.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-BoldItalic.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-ExtraBold.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-Italic.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-Light.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-LightItalic.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-Medium.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-MediumItalic.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-Regular.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-SemiBold.ttf +0 -0
- package/src/assets/fonts/figtree/static/Figtree-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/inter/Inter-Bold.ttf +0 -0
- package/src/assets/fonts/inter/Inter-Bold.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Medium.ttf +0 -0
- package/src/assets/fonts/inter/Inter-Medium.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Regular.ttf +0 -0
- package/src/assets/fonts/inter/Inter-Regular.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-SemiBold.ttf +0 -0
- package/src/assets/fonts/inter/Inter-SemiBold.woff2 +0 -0
- package/src/assets/fonts/inter/inter.css +49 -0
- package/src/assets/fonts/rajdhani/OFL.txt +91 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Bold.ttf +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Bold.woff +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Bold.woff2 +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Light.ttf +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Medium.ttf +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Medium.woff +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Medium.woff2 +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Regular.ttf +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Regular.woff +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-Regular.woff2 +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-SemiBold.ttf +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-SemiBold.woff +0 -0
- package/src/assets/fonts/rajdhani/Rajdhani-SemiBold.woff2 +0 -0
- package/src/assets/fonts/rajdhani/rajdhani.css +53 -0
- package/src/blend/BlendCalculator.ts +120 -0
- package/src/blend/ColorSpaceUtils.ts +325 -0
- package/src/blend/OklchBlendCalculator.ts +79 -0
- package/src/blend/ThemeAwareBlendUtilities.android.kt +367 -0
- package/src/blend/ThemeAwareBlendUtilities.ios.swift +325 -0
- package/src/blend/ThemeAwareBlendUtilities.web.ts +315 -0
- package/src/blend/__tests__/BlendCalculator.test.ts +393 -0
- package/src/blend/__tests__/BlendUtilities.property.test.ts +600 -0
- package/src/blend/__tests__/ColorSpaceUtils.test.ts +885 -0
- package/src/blend/__tests__/InteractionStateAudit.test.ts +235 -0
- package/src/blend/__tests__/OklchBlendCalculator.test.ts +134 -0
- package/src/blend/__tests__/ThemeAwareBlendUtilities.test.ts +200 -0
- package/src/blend/__tests__/ThemeSwitching.test.ts +508 -0
- package/src/blend/index.ts +37 -0
- package/src/browser-entry.ts +270 -0
- package/src/build/.gitkeep +1 -0
- package/src/build/BuildOrchestrator.ts +663 -0
- package/src/build/__tests__/AndroidBuildIntegration.test.ts +437 -0
- package/src/build/__tests__/AndroidMotionTokenGeneration.test.ts +256 -0
- package/src/build/__tests__/BuildOrchestrator.test.ts +562 -0
- package/src/build/__tests__/MotionTokenCrossPlatformIntegration.test.ts +424 -0
- package/src/build/__tests__/WebCSSTokenGeneration.test.ts +271 -0
- package/src/build/__tests__/WebMotionTokenGeneration.test.ts +305 -0
- package/src/build/__tests__/WebNPMPackageStructure.test.ts +447 -0
- package/src/build/__tests__/iOSMotionTokenGeneration.test.ts +298 -0
- package/src/build/errors/BuildError.ts +140 -0
- package/src/build/errors/ErrorDocumentation.ts +638 -0
- package/src/build/errors/ErrorHandler.ts +406 -0
- package/src/build/errors/ErrorReporter.ts +573 -0
- package/src/build/errors/PlatformGenerationError.ts +201 -0
- package/src/build/errors/README.md +486 -0
- package/src/build/errors/RecoveryStrategy.ts +393 -0
- package/src/build/errors/TokenGenerationError.ts +196 -0
- package/src/build/errors/TokenReferenceError.ts +204 -0
- package/src/build/errors/__tests__/BuildError.test.ts +212 -0
- package/src/build/errors/__tests__/ErrorDocumentation.example.ts +272 -0
- package/src/build/errors/__tests__/ErrorDocumentation.test.ts +458 -0
- package/src/build/errors/__tests__/ErrorHandler.integration.test.ts +295 -0
- package/src/build/errors/__tests__/ErrorHandler.test.ts +497 -0
- package/src/build/errors/__tests__/ErrorReporter.test.ts +581 -0
- package/src/build/errors/__tests__/MotionTokenErrors.test.ts +392 -0
- package/src/build/errors/__tests__/RecoveryStrategy.test.ts +643 -0
- package/src/build/errors/index.ts +90 -0
- package/src/build/index.ts +73 -0
- package/src/build/orchestration/IncrementalBuilder.ts +532 -0
- package/src/build/orchestration/ParallelExecutor.ts +336 -0
- package/src/build/orchestration/ProgressTracker.ts +582 -0
- package/src/build/orchestration/SequentialExecutor.ts +305 -0
- package/src/build/orchestration/__tests__/IncrementalBuilder.test.ts +354 -0
- package/src/build/orchestration/__tests__/ParallelExecutor.integration.test.ts +295 -0
- package/src/build/orchestration/__tests__/ParallelExecutor.test.ts +493 -0
- package/src/build/orchestration/__tests__/ProgressTracker.test.ts +529 -0
- package/src/build/orchestration/__tests__/SequentialExecutor.integration.test.ts +202 -0
- package/src/build/orchestration/__tests__/SequentialExecutor.test.ts +232 -0
- package/src/build/orchestration/index.ts +35 -0
- package/src/build/platforms/.gitkeep +1 -0
- package/src/build/platforms/AndroidBuilder.ts +1366 -0
- package/src/build/platforms/AndroidShadowGenerator.ts +394 -0
- package/src/build/platforms/IOSShadowGenerator.ts +324 -0
- package/src/build/platforms/PlatformBuilder.ts +131 -0
- package/src/build/platforms/WebBuilder.ts +1414 -0
- package/src/build/platforms/WebShadowGenerator.ts +288 -0
- package/src/build/platforms/__tests__/AndroidBuilder.tokenGeneration.test.ts +146 -0
- package/src/build/platforms/__tests__/AndroidShadowGenerator.test.ts +195 -0
- package/src/build/platforms/__tests__/IOSShadowGenerator.test.ts +156 -0
- package/src/build/platforms/__tests__/WebShadowGenerator.test.ts +123 -0
- package/src/build/platforms/__tests__/iOSBuilder.test.ts +1599 -0
- package/src/build/platforms/iOSBuilder.ts +1746 -0
- package/src/build/platforms/index.ts +9 -0
- package/src/build/product/ProductTokenGenerator.ts +162 -0
- package/src/build/product/TokenIndexReader.ts +78 -0
- package/src/build/product/__tests__/KotlinEmitter.test.ts +109 -0
- package/src/build/product/__tests__/ProductTokenGenerator.test.ts +135 -0
- package/src/build/product/__tests__/SwiftEmitter.test.ts +90 -0
- package/src/build/product/__tests__/TokenIndexReader.test.ts +85 -0
- package/src/build/product/__tests__/WebEmitter.test.ts +111 -0
- package/src/build/product/__tests__/fixtures/tokens/layout.yaml +21 -0
- package/src/build/product/__tests__/fixtures/tokens/motion.yaml +11 -0
- package/src/build/product/__tests__/fixtures/tokens/visualization.yaml +8 -0
- package/src/build/product/emitters/KotlinEmitter.ts +83 -0
- package/src/build/product/emitters/SwiftEmitter.ts +95 -0
- package/src/build/product/emitters/WebEmitter.ts +69 -0
- package/src/build/tokens/.gitkeep +1 -0
- package/src/build/tokens/ComponentToken.ts +285 -0
- package/src/build/tokens/ComponentTokenGenerator.ts +376 -0
- package/src/build/tokens/PlatformTokens.ts +188 -0
- package/src/build/tokens/TokenIntegrator.ts +410 -0
- package/src/build/tokens/TokenSelection.ts +130 -0
- package/src/build/tokens/TokenSelector.ts +394 -0
- package/src/build/tokens/UnitConverter.ts +320 -0
- package/src/build/tokens/__tests__/ClassInvariantGuard.test.ts +167 -0
- package/src/build/tokens/__tests__/ComponentTokenGenerator.test.ts +285 -0
- package/src/build/tokens/__tests__/TokenIntegrator.test.ts +319 -0
- package/src/build/tokens/__tests__/TokenSelector.test.ts +264 -0
- package/src/build/tokens/__tests__/UnitConverter.applyScaleWithRounding.test.ts +160 -0
- package/src/build/tokens/__tests__/UnitConverter.test.ts +331 -0
- package/src/build/tokens/__tests__/brand-dual-instance.test.ts +135 -0
- package/src/build/tokens/__tests__/defineComponentTokens.test.ts +440 -0
- package/src/build/tokens/defineComponentTokens.ts +286 -0
- package/src/build/tokens/index.ts +44 -0
- package/src/build/tokens/types.ts +26 -0
- package/src/build/types/.gitkeep +1 -0
- package/src/build/types/BuildConfig.ts +123 -0
- package/src/build/types/BuildOrchestrator.ts +114 -0
- package/src/build/types/BuildResult.ts +125 -0
- package/src/build/types/Platform.ts +49 -0
- package/src/build/types/index.ts +39 -0
- package/src/build/validation/.gitkeep +1 -0
- package/src/build/validation/AndroidBuildValidator.ts +630 -0
- package/src/build/validation/CrossPlatformValidationReporter.ts +1267 -0
- package/src/build/validation/InterfaceContractValidator.ts +417 -0
- package/src/build/validation/InterfaceValidator.ts +326 -0
- package/src/build/validation/MathematicalConsistencyValidator.ts +874 -0
- package/src/build/validation/MethodSignatureValidator.ts +374 -0
- package/src/build/validation/PropertyTypeValidator.ts +312 -0
- package/src/build/validation/TokenComparator.ts +796 -0
- package/src/build/validation/ValidationReporter.example.ts +310 -0
- package/src/build/validation/ValidationReporter.ts +745 -0
- package/src/build/validation/WebBuildValidator.ts +583 -0
- package/src/build/validation/__tests__/AndroidBuildValidator.test.ts +522 -0
- package/src/build/validation/__tests__/CrossPlatformValidationReporter.test.ts +593 -0
- package/src/build/validation/__tests__/InterfaceContractValidator.test.ts +647 -0
- package/src/build/validation/__tests__/InterfaceValidation.functional.test.ts +360 -0
- package/src/build/validation/__tests__/InterfaceValidator.test.ts +318 -0
- package/src/build/validation/__tests__/MethodSignatureValidator.test.ts +625 -0
- package/src/build/validation/__tests__/MotionTokenCrossPlatformValidation.test.ts +305 -0
- package/src/build/validation/__tests__/MotionTokenValidation.test.ts +309 -0
- package/src/build/validation/__tests__/PropertyTypeValidator.test.ts +557 -0
- package/src/build/validation/__tests__/TokenComparator.test.ts +358 -0
- package/src/build/validation/__tests__/ValidationReporter.integration.test.ts +424 -0
- package/src/build/validation/__tests__/ValidationReporter.test.ts +793 -0
- package/src/build/validation/__tests__/WebBuildValidator.test.ts +495 -0
- package/src/build/validation/iOSBuildValidator.ts +783 -0
- package/src/build/validation/index.ts +74 -0
- package/src/build/validation/types/InterfaceDefinition.ts +101 -0
- package/src/build/validation/types/ValidationResult.ts +114 -0
- package/src/build/workflow/BuildMode.ts +336 -0
- package/src/build/workflow/CICDIntegration.ts +503 -0
- package/src/build/workflow/ConfigHelpers.example.ts +317 -0
- package/src/build/workflow/ConfigHelpers.ts +834 -0
- package/src/build/workflow/README.md +327 -0
- package/src/build/workflow/SourceMapGenerator.ts +362 -0
- package/src/build/workflow/__tests__/BuildMode.test.ts +544 -0
- package/src/build/workflow/__tests__/CICDIntegration.test.ts +591 -0
- package/src/build/workflow/__tests__/ConfigHelpers.test.ts +559 -0
- package/src/build/workflow/__tests__/SourceMapGenerator.test.ts +421 -0
- package/src/build/workflow/index.ts +42 -0
- package/src/cli/__tests__/Applier.test.ts +202 -0
- package/src/cli/__tests__/Classifier.test.ts +187 -0
- package/src/cli/__tests__/FileScanner.test.ts +108 -0
- package/src/cli/__tests__/IgnoreFilter.test.ts +92 -0
- package/src/cli/__tests__/Manifest.test.ts +107 -0
- package/src/cli/__tests__/PackageResolver.test.ts +66 -0
- package/src/cli/__tests__/Prompter.test.ts +165 -0
- package/src/cli/__tests__/Reporter.test.ts +128 -0
- package/src/cli/__tests__/backward-compat.test.ts +142 -0
- package/src/cli/__tests__/figma-extract.test.ts +342 -0
- package/src/cli/__tests__/figma-push.test.ts +350 -0
- package/src/cli/__tests__/init.test.ts +259 -0
- package/src/cli/__tests__/loadComponentTokens.test.ts +187 -0
- package/src/cli/__tests__/pipeline-independence.test.ts +127 -0
- package/src/cli/__tests__/product-only.test.ts +130 -0
- package/src/cli/__tests__/resolveTokens.test.ts +88 -0
- package/src/cli/__tests__/staleness.test.ts +132 -0
- package/src/cli/__tests__/sync.test.ts +199 -0
- package/src/cli/__tests__/validate.test.ts +69 -0
- package/src/cli/designerpunk.ts +410 -0
- package/src/cli/figma-extract.ts +331 -0
- package/src/cli/figma-push.ts +288 -0
- package/src/cli/generateProductTokens.ts +69 -0
- package/src/cli/init.ts +481 -0
- package/src/cli/loadComponentTokens.ts +145 -0
- package/src/cli/resolveTokens.ts +123 -0
- package/src/cli/shared/mcpDataRoots.ts +122 -0
- package/src/cli/shared/resolvePackageRoot.ts +58 -0
- package/src/cli/shared/transforms.ts +18 -0
- package/src/cli/staleness.ts +81 -0
- package/src/cli/sync/Applier.ts +128 -0
- package/src/cli/sync/Classifier.ts +130 -0
- package/src/cli/sync/FileScanner.ts +64 -0
- package/src/cli/sync/IgnoreFilter.ts +44 -0
- package/src/cli/sync/Manifest.ts +64 -0
- package/src/cli/sync/PackageResolver.ts +40 -0
- package/src/cli/sync/Prompter.ts +173 -0
- package/src/cli/sync/Reporter.ts +78 -0
- package/src/cli/sync/SteeringDirCheck.ts +166 -0
- package/src/cli/sync/index.ts +115 -0
- package/src/cli/templates/mcp-config.json.template +46 -0
- package/src/cli/validate.ts +135 -0
- package/src/cli/validateProductTokens.ts +55 -0
- package/src/color/OklchConverter.ts +284 -0
- package/src/color/OklchValidator.ts +186 -0
- package/src/color/__tests__/OklchConverter.test.ts +232 -0
- package/src/color/__tests__/OklchRegression.test.ts +101 -0
- package/src/color/__tests__/OklchValidator.test.ts +199 -0
- package/src/color/__tests__/WcagContrast.test.ts +76 -0
- package/src/components/__tests__/BlendTokenUsageValidation.test.ts +726 -0
- package/src/components/__tests__/DynamicImportGuard.test.ts +226 -0
- package/src/components/__tests__/ExtensionLintPolicy.test.ts +113 -0
- package/src/components/__tests__/TokenCompliance.test.ts +921 -0
- package/src/components/__tests__/colorInheritanceValidation.test.ts +267 -0
- package/src/components/__tests__/componentTypographyInheritance.test.ts +326 -0
- package/src/components/core/Avatar-Base/Avatar-Base.schema.yaml +113 -0
- package/src/components/core/Avatar-Base/README.md +366 -0
- package/src/components/core/Avatar-Base/__tests__/.gitkeep +3 -0
- package/src/components/core/Avatar-Base/__tests__/Avatar.accessibility.test.ts +483 -0
- package/src/components/core/Avatar-Base/__tests__/Avatar.icon-integration.test.ts +656 -0
- package/src/components/core/Avatar-Base/__tests__/Avatar.image.test.ts +393 -0
- package/src/components/core/Avatar-Base/__tests__/Avatar.lifecycle.test.ts +545 -0
- package/src/components/core/Avatar-Base/__tests__/Avatar.rendering.test.ts +505 -0
- package/src/components/core/Avatar-Base/__tests__/Avatar.test.ts +692 -0
- package/src/components/core/Avatar-Base/avatar.tokens.ts +376 -0
- package/src/components/core/Avatar-Base/component-meta.yaml +20 -0
- package/src/components/core/Avatar-Base/contracts.yaml +212 -0
- package/src/components/core/Avatar-Base/index.ts +25 -0
- package/src/components/core/Avatar-Base/platforms/android/.gitkeep +3 -0
- package/src/components/core/Avatar-Base/platforms/android/Avatar.android.kt +593 -0
- package/src/components/core/Avatar-Base/platforms/android/AvatarPreview.kt +1106 -0
- package/src/components/core/Avatar-Base/platforms/android/HexagonShape.kt +297 -0
- package/src/components/core/Avatar-Base/platforms/ios/.gitkeep +3 -0
- package/src/components/core/Avatar-Base/platforms/ios/Avatar.ios.swift +815 -0
- package/src/components/core/Avatar-Base/platforms/ios/AvatarPreview.swift +773 -0
- package/src/components/core/Avatar-Base/platforms/ios/RoundedPointyTopHexagon.swift +360 -0
- package/src/components/core/Avatar-Base/platforms/web/.gitkeep +3 -0
- package/src/components/core/Avatar-Base/platforms/web/Avatar.styles.css +595 -0
- package/src/components/core/Avatar-Base/platforms/web/Avatar.web.ts +873 -0
- package/src/components/core/Avatar-Base/platforms/web/hexagon-clip.svg +87 -0
- package/src/components/core/Avatar-Base/tokens/.gitkeep +4 -0
- package/src/components/core/Avatar-Base/types.ts +86 -0
- package/src/components/core/Badge-Count-Base/Badge-Count-Base.schema.yaml +122 -0
- package/src/components/core/Badge-Count-Base/README.md +323 -0
- package/src/components/core/Badge-Count-Base/__tests__/BadgeCountBase.stemma.test.ts +548 -0
- package/src/components/core/Badge-Count-Base/__tests__/BadgeCountBase.test.ts +452 -0
- package/src/components/core/Badge-Count-Base/__tests__/test-utils.ts +244 -0
- package/src/components/core/Badge-Count-Base/component-meta.yaml +23 -0
- package/src/components/core/Badge-Count-Base/contracts.yaml +173 -0
- package/src/components/core/Badge-Count-Base/index.ts +37 -0
- package/src/components/core/Badge-Count-Base/platforms/android/.gitkeep +1 -0
- package/src/components/core/Badge-Count-Base/platforms/android/BadgeCountBase.android.kt +581 -0
- package/src/components/core/Badge-Count-Base/platforms/ios/.gitkeep +1 -0
- package/src/components/core/Badge-Count-Base/platforms/ios/BadgeCountBase.ios.swift +502 -0
- package/src/components/core/Badge-Count-Base/platforms/web/BadgeCountBase.styles.css +148 -0
- package/src/components/core/Badge-Count-Base/platforms/web/BadgeCountBase.web.ts +363 -0
- package/src/components/core/Badge-Count-Base/types.ts +150 -0
- package/src/components/core/Badge-Count-Notification/Badge-Count-Notification.schema.yaml +108 -0
- package/src/components/core/Badge-Count-Notification/README.md +396 -0
- package/src/components/core/Badge-Count-Notification/__tests__/BadgeCountNotification.stemma.test.ts +571 -0
- package/src/components/core/Badge-Count-Notification/__tests__/BadgeCountNotification.test.ts +490 -0
- package/src/components/core/Badge-Count-Notification/__tests__/test-utils.ts +256 -0
- package/src/components/core/Badge-Count-Notification/component-meta.yaml +20 -0
- package/src/components/core/Badge-Count-Notification/contracts.yaml +92 -0
- package/src/components/core/Badge-Count-Notification/index.ts +60 -0
- package/src/components/core/Badge-Count-Notification/platforms/android/.gitkeep +2 -0
- package/src/components/core/Badge-Count-Notification/platforms/android/BadgeCountNotification.android.kt +818 -0
- package/src/components/core/Badge-Count-Notification/platforms/ios/BadgeCountNotification.ios.swift +660 -0
- package/src/components/core/Badge-Count-Notification/platforms/web/BadgeCountNotification.styles.css +182 -0
- package/src/components/core/Badge-Count-Notification/platforms/web/BadgeCountNotification.web.ts +401 -0
- package/src/components/core/Badge-Count-Notification/tokens.ts +124 -0
- package/src/components/core/Badge-Count-Notification/types.ts +119 -0
- package/src/components/core/Badge-Label-Base/Badge-Label-Base.schema.yaml +131 -0
- package/src/components/core/Badge-Label-Base/README.md +251 -0
- package/src/components/core/Badge-Label-Base/__tests__/BadgeLabelBase.stemma.test.ts +549 -0
- package/src/components/core/Badge-Label-Base/__tests__/BadgeLabelBase.test.ts +439 -0
- package/src/components/core/Badge-Label-Base/__tests__/test-utils.ts +269 -0
- package/src/components/core/Badge-Label-Base/__tests__/tokens.test.ts +88 -0
- package/src/components/core/Badge-Label-Base/component-meta.yaml +21 -0
- package/src/components/core/Badge-Label-Base/contracts.yaml +148 -0
- package/src/components/core/Badge-Label-Base/index.ts +41 -0
- package/src/components/core/Badge-Label-Base/platforms/android/BadgeLabelBase.android.kt +452 -0
- package/src/components/core/Badge-Label-Base/platforms/ios/BadgeLabelBase.ios.swift +483 -0
- package/src/components/core/Badge-Label-Base/platforms/web/BadgeLabelBase.styles.css +166 -0
- package/src/components/core/Badge-Label-Base/platforms/web/BadgeLabelBase.web.ts +340 -0
- package/src/components/core/Badge-Label-Base/tokens.ts +80 -0
- package/src/components/core/Badge-Label-Base/types.ts +148 -0
- package/src/components/core/Button-CTA/Button-CTA.schema.yaml +259 -0
- package/src/components/core/Button-CTA/Button-CTA.tokens.ts +79 -0
- package/src/components/core/Button-CTA/README.md +296 -0
- package/src/components/core/Button-CTA/__tests__/ButtonCTA.alignment.test.ts +355 -0
- package/src/components/core/Button-CTA/__tests__/ButtonCTA.test.ts +752 -0
- package/src/components/core/Button-CTA/__tests__/ButtonCTA.tokens.test.ts +89 -0
- package/src/components/core/Button-CTA/__tests__/setup.test.ts +211 -0
- package/src/components/core/Button-CTA/__tests__/test-utils.ts +187 -0
- package/src/components/core/Button-CTA/component-meta.yaml +25 -0
- package/src/components/core/Button-CTA/contracts.yaml +140 -0
- package/src/components/core/Button-CTA/examples/BasicUsage.html +145 -0
- package/src/components/core/Button-CTA/examples/BasicUsage.tsx +246 -0
- package/src/components/core/Button-CTA/examples/Variants.html +263 -0
- package/src/components/core/Button-CTA/examples/WithIcon.html +166 -0
- package/src/components/core/Button-CTA/index.ts +20 -0
- package/src/components/core/Button-CTA/platforms/android/ButtonCTA.android.kt +405 -0
- package/src/components/core/Button-CTA/platforms/ios/ButtonCTA.ios.swift +552 -0
- package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.css +419 -0
- package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.ts +697 -0
- package/src/components/core/Button-CTA/platforms/web/__tests__/ButtonCTA.icon-integration.test.ts +476 -0
- package/src/components/core/Button-CTA/types.ts +257 -0
- package/src/components/core/Button-Icon/Button-Icon.schema.yaml +114 -0
- package/src/components/core/Button-Icon/README.md +371 -0
- package/src/components/core/Button-Icon/__tests__/ButtonIcon.alignment.test.ts +358 -0
- package/src/components/core/Button-Icon/__tests__/ButtonIcon.properties-8-13.test.ts +953 -0
- package/src/components/core/Button-Icon/__tests__/ButtonIcon.properties.test.ts +920 -0
- package/src/components/core/Button-Icon/__tests__/ButtonIcon.stemma.test.ts +622 -0
- package/src/components/core/Button-Icon/__tests__/ButtonIcon.unit.test.ts +560 -0
- package/src/components/core/Button-Icon/__tests__/setup.test.ts +361 -0
- package/src/components/core/Button-Icon/__tests__/test-utils.ts +248 -0
- package/src/components/core/Button-Icon/buttonIcon.tokens.ts +202 -0
- package/src/components/core/Button-Icon/component-meta.yaml +24 -0
- package/src/components/core/Button-Icon/contracts.yaml +228 -0
- package/src/components/core/Button-Icon/platforms/android/ButtonIcon.android.kt +548 -0
- package/src/components/core/Button-Icon/platforms/ios/ButtonIcon.ios.swift +482 -0
- package/src/components/core/Button-Icon/platforms/web/.gitkeep +4 -0
- package/src/components/core/Button-Icon/platforms/web/ButtonIcon.web.css +600 -0
- package/src/components/core/Button-Icon/platforms/web/ButtonIcon.web.ts +625 -0
- package/src/components/core/Button-Icon/types.ts +186 -0
- package/src/components/core/Button-VerticalList-Item/Button-VerticalList-Item.schema.yaml +138 -0
- package/src/components/core/Button-VerticalList-Item/Button-VerticalList-Item.tokens.ts +112 -0
- package/src/components/core/Button-VerticalList-Item/README.md +450 -0
- package/src/components/core/Button-VerticalList-Item/__tests__/.gitkeep +2 -0
- package/src/components/core/Button-VerticalList-Item/__tests__/ButtonVerticalListItem.alignment.test.ts +271 -0
- package/src/components/core/Button-VerticalList-Item/__tests__/ButtonVerticalListItem.failLoudly.test.ts +106 -0
- package/src/components/core/Button-VerticalList-Item/__tests__/ButtonVerticalListItem.integration.test.ts +480 -0
- package/src/components/core/Button-VerticalList-Item/__tests__/ButtonVerticalListItem.properties.test.ts +634 -0
- package/src/components/core/Button-VerticalList-Item/__tests__/ButtonVerticalListItem.unit.test.ts +746 -0
- package/src/components/core/Button-VerticalList-Item/__tests__/rtlSupport.test.ts +206 -0
- package/src/components/core/Button-VerticalList-Item/__tests__/test-utils.ts +297 -0
- package/src/components/core/Button-VerticalList-Item/__tests__/visualStateMapping.test.ts +419 -0
- package/src/components/core/Button-VerticalList-Item/component-meta.yaml +24 -0
- package/src/components/core/Button-VerticalList-Item/contracts.yaml +138 -0
- package/src/components/core/Button-VerticalList-Item/index.ts +49 -0
- package/src/components/core/Button-VerticalList-Item/platforms/android/.gitkeep +2 -0
- package/src/components/core/Button-VerticalList-Item/platforms/android/VerticalListButtonItem.android.kt +594 -0
- package/src/components/core/Button-VerticalList-Item/platforms/android/VerticalListButtonItemTest.kt +1109 -0
- package/src/components/core/Button-VerticalList-Item/platforms/android/VisualStateStyles.kt +585 -0
- package/src/components/core/Button-VerticalList-Item/platforms/ios/.gitkeep +2 -0
- package/src/components/core/Button-VerticalList-Item/platforms/ios/VerticalListButtonItem.ios.swift +853 -0
- package/src/components/core/Button-VerticalList-Item/platforms/ios/VerticalListButtonItemTests.swift +794 -0
- package/src/components/core/Button-VerticalList-Item/platforms/ios/VisualStateStyles.swift +453 -0
- package/src/components/core/Button-VerticalList-Item/platforms/web/.gitkeep +2 -0
- package/src/components/core/Button-VerticalList-Item/platforms/web/ButtonVerticalListItem.styles.css +459 -0
- package/src/components/core/Button-VerticalList-Item/platforms/web/ButtonVerticalListItem.web.ts +1030 -0
- package/src/components/core/Button-VerticalList-Item/platforms/web/visualStateMapping.ts +411 -0
- package/src/components/core/Button-VerticalList-Item/types.ts +338 -0
- package/src/components/core/Button-VerticalList-Set/Button-VerticalList-Set.schema.yaml +110 -0
- package/src/components/core/Button-VerticalList-Set/README.md +578 -0
- package/src/components/core/Button-VerticalList-Set/__tests__/.gitkeep +5 -0
- package/src/components/core/Button-VerticalList-Set/__tests__/ButtonVerticalListSet.integration.test.ts +676 -0
- package/src/components/core/Button-VerticalList-Set/__tests__/ButtonVerticalListSet.property.test.ts +786 -0
- package/src/components/core/Button-VerticalList-Set/__tests__/ButtonVerticalListSet.property2.test.ts +1109 -0
- package/src/components/core/Button-VerticalList-Set/__tests__/ButtonVerticalListSet.unit.test.ts +924 -0
- package/src/components/core/Button-VerticalList-Set/__tests__/animationTiming.test.ts +182 -0
- package/src/components/core/Button-VerticalList-Set/__tests__/crossPlatformConsistency.test.ts +685 -0
- package/src/components/core/Button-VerticalList-Set/__tests__/deriveItemStates.test.ts +179 -0
- package/src/components/core/Button-VerticalList-Set/__tests__/validation.test.ts +275 -0
- package/src/components/core/Button-VerticalList-Set/component-meta.yaml +22 -0
- package/src/components/core/Button-VerticalList-Set/contracts.yaml +170 -0
- package/src/components/core/Button-VerticalList-Set/index.ts +32 -0
- package/src/components/core/Button-VerticalList-Set/platforms/android/.gitkeep +0 -0
- package/src/components/core/Button-VerticalList-Set/platforms/android/ButtonVerticalListSet.android.kt +805 -0
- package/src/components/core/Button-VerticalList-Set/platforms/android/ButtonVerticalListSetPreview.kt +390 -0
- package/src/components/core/Button-VerticalList-Set/platforms/android/ButtonVerticalListSetTest.kt +961 -0
- package/src/components/core/Button-VerticalList-Set/platforms/ios/.gitkeep +0 -0
- package/src/components/core/Button-VerticalList-Set/platforms/ios/ButtonVerticalListSet.ios.swift +1127 -0
- package/src/components/core/Button-VerticalList-Set/platforms/ios/ButtonVerticalListSetPreview.swift +664 -0
- package/src/components/core/Button-VerticalList-Set/platforms/ios/ButtonVerticalListSetTests.swift +475 -0
- package/src/components/core/Button-VerticalList-Set/platforms/web/.gitkeep +4 -0
- package/src/components/core/Button-VerticalList-Set/platforms/web/Button-VerticalList-Set.styles.css +167 -0
- package/src/components/core/Button-VerticalList-Set/platforms/web/ButtonVerticalListSet.web.ts +1446 -0
- package/src/components/core/Button-VerticalList-Set/types.ts +788 -0
- package/src/components/core/Chip-Base/Chip-Base.schema.yaml +214 -0
- package/src/components/core/Chip-Base/__tests__/ChipBase.test.ts +521 -0
- package/src/components/core/Chip-Base/component-meta.yaml +25 -0
- package/src/components/core/Chip-Base/contracts.yaml +201 -0
- package/src/components/core/Chip-Base/index.ts +40 -0
- package/src/components/core/Chip-Base/platforms/android/ChipBase.android.kt +379 -0
- package/src/components/core/Chip-Base/platforms/ios/.gitkeep +3 -0
- package/src/components/core/Chip-Base/platforms/ios/ChipBase.ios.swift +420 -0
- package/src/components/core/Chip-Base/platforms/web/.gitkeep +5 -0
- package/src/components/core/Chip-Base/platforms/web/ChipBase.styles.css +280 -0
- package/src/components/core/Chip-Base/platforms/web/ChipBase.web.ts +480 -0
- package/src/components/core/Chip-Base/types.ts +189 -0
- package/src/components/core/Chip-Filter/Chip-Filter.schema.yaml +181 -0
- package/src/components/core/Chip-Filter/__tests__/ChipFilter.test.ts +579 -0
- package/src/components/core/Chip-Filter/component-meta.yaml +20 -0
- package/src/components/core/Chip-Filter/contracts.yaml +76 -0
- package/src/components/core/Chip-Filter/index.ts +34 -0
- package/src/components/core/Chip-Filter/platforms/android/ChipFilter.android.kt +484 -0
- package/src/components/core/Chip-Filter/platforms/ios/ChipFilter.ios.swift +510 -0
- package/src/components/core/Chip-Filter/platforms/web/ChipFilter.styles.css +105 -0
- package/src/components/core/Chip-Filter/platforms/web/ChipFilter.web.ts +539 -0
- package/src/components/core/Chip-Filter/types.ts +47 -0
- package/src/components/core/Chip-Input/Chip-Input.schema.yaml +173 -0
- package/src/components/core/Chip-Input/__tests__/ChipInput.test.ts +459 -0
- package/src/components/core/Chip-Input/component-meta.yaml +20 -0
- package/src/components/core/Chip-Input/contracts.yaml +75 -0
- package/src/components/core/Chip-Input/index.ts +35 -0
- package/src/components/core/Chip-Input/platforms/android/.gitkeep +3 -0
- package/src/components/core/Chip-Input/platforms/android/ChipInput.android.kt +409 -0
- package/src/components/core/Chip-Input/platforms/ios/.gitkeep +3 -0
- package/src/components/core/Chip-Input/platforms/ios/ChipInput.ios.swift +449 -0
- package/src/components/core/Chip-Input/platforms/web/ChipInput.styles.css +99 -0
- package/src/components/core/Chip-Input/platforms/web/ChipInput.web.ts +485 -0
- package/src/components/core/Chip-Input/types.ts +35 -0
- package/src/components/core/Container-Base/Container-Base.schema.yaml +411 -0
- package/src/components/core/Container-Base/README.md +450 -0
- package/src/components/core/Container-Base/__tests__/ContainerBase.test.ts +712 -0
- package/src/components/core/Container-Base/component-meta.yaml +22 -0
- package/src/components/core/Container-Base/contracts.yaml +118 -0
- package/src/components/core/Container-Base/index.ts +47 -0
- package/src/components/core/Container-Base/platforms/android/ContainerBase.android.kt +654 -0
- package/src/components/core/Container-Base/platforms/android/TokenMapping.kt +558 -0
- package/src/components/core/Container-Base/platforms/ios/ContainerBase.ios.swift +699 -0
- package/src/components/core/Container-Base/platforms/ios/TokenMapping.swift +493 -0
- package/src/components/core/Container-Base/platforms/web/ContainerBase.web.ts +405 -0
- package/src/components/core/Container-Base/platforms/web/styles.css +198 -0
- package/src/components/core/Container-Base/platforms/web/token-mapping.ts +573 -0
- package/src/components/core/Container-Base/tokens.ts +241 -0
- package/src/components/core/Container-Base/types.ts +307 -0
- package/src/components/core/Container-Card-Base/Container-Card-Base.schema.yaml +374 -0
- package/src/components/core/Container-Card-Base/README.md +506 -0
- package/src/components/core/Container-Card-Base/__tests__/ContainerCardBase.composition.test.ts +167 -0
- package/src/components/core/Container-Card-Base/__tests__/ContainerCardBase.test.ts +646 -0
- package/src/components/core/Container-Card-Base/component-meta.yaml +21 -0
- package/src/components/core/Container-Card-Base/contracts.yaml +129 -0
- package/src/components/core/Container-Card-Base/index.ts +64 -0
- package/src/components/core/Container-Card-Base/platforms/android/ContainerCardBase.android.kt +800 -0
- package/src/components/core/Container-Card-Base/platforms/ios/ContainerCardBase.ios.swift +962 -0
- package/src/components/core/Container-Card-Base/platforms/web/ContainerCardBase.web.ts +373 -0
- package/src/components/core/Container-Card-Base/tokens.ts +224 -0
- package/src/components/core/Container-Card-Base/types.ts +332 -0
- package/src/components/core/Icon-Base/Icon-Base.schema.yaml +206 -0
- package/src/components/core/Icon-Base/README.md +168 -0
- package/src/components/core/Icon-Base/__tests__/IconBase.test.ts +192 -0
- package/src/components/core/Icon-Base/component-meta.yaml +22 -0
- package/src/components/core/Icon-Base/contracts.yaml +89 -0
- package/src/components/core/Icon-Base/index.ts +34 -0
- package/src/components/core/Icon-Base/platforms/android/IconBase.android.kt +240 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/README.md +255 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/alert_circle.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/arrow_down.xml +17 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/arrow_left.xml +17 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/arrow_right.xml +17 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/arrow_up.xml +17 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/award.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/bell.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/briefcase.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/calendar.xml +34 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/check.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/check_circle.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/chevron_down.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/chevron_left.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/chevron_right.xml +12 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/circle.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/clock.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/credit_card.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/dollar_sign.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/external_link.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/eye.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/eye_off.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/file_text.xml +41 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/filter.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/globe.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/heart.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/info.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/mail.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/map_pin.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/minus.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/more_horizontal.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/more_vertical.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/phone.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/plus.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/refresh_cw.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/save.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/search.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/settings.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/share.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/share_2.xml +41 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/shield.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/smartphone.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/smile.xml +34 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/star.xml +13 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/trending_up.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/user.xml +20 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/user_check.xml +27 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/user_x.xml +34 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/users.xml +34 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/wifi.xml +34 -0
- package/src/components/core/Icon-Base/platforms/android/res/drawable/x.xml +20 -0
- package/src/components/core/Icon-Base/platforms/ios/ASSET_CATALOG_SETUP.md +239 -0
- package/src/components/core/Icon-Base/platforms/ios/IconBase.ios.swift +296 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Contents.json +6 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/Contents.json +9 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/alert-circle.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/alert-circle.imageset/alert-circle.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/arrow-down.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/arrow-down.imageset/arrow-down.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/arrow-left.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/arrow-left.imageset/arrow-left.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/arrow-right.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/arrow-right.imageset/arrow-right.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/arrow-up.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/arrow-up.imageset/arrow-up.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/award.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/award.imageset/award.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/bell.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/bell.imageset/bell.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/briefcase.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/briefcase.imageset/briefcase.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/calendar.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/calendar.imageset/calendar.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/check-circle.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/check-circle.imageset/check-circle.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/check.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/check.imageset/check.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/chevron-down.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/chevron-down.imageset/chevron-down.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/chevron-left.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/chevron-left.imageset/chevron-left.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/chevron-right.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/chevron-right.imageset/chevron-right.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/circle.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/circle.imageset/circle.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/clock.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/clock.imageset/clock.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/credit-card.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/credit-card.imageset/credit-card.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/dollar-sign.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/dollar-sign.imageset/dollar-sign.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/external-link.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/external-link.imageset/external-link.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/eye-off.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/eye-off.imageset/eye-off.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/eye.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/eye.imageset/eye.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/file-text.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/file-text.imageset/file-text.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/filter.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/filter.imageset/filter.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/globe.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/globe.imageset/globe.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/heart.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/heart.imageset/heart.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/info.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/info.imageset/info.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/mail.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/mail.imageset/mail.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/map-pin.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/map-pin.imageset/map-pin.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/minus.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/minus.imageset/minus.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/more-horizontal.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/more-horizontal.imageset/more-horizontal.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/more-vertical.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/more-vertical.imageset/more-vertical.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/phone.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/phone.imageset/phone.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/plus.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/plus.imageset/plus.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/refresh-cw.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/refresh-cw.imageset/refresh-cw.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/save.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/save.imageset/save.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/search.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/search.imageset/search.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/settings.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/settings.imageset/settings.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/share-2.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/share-2.imageset/share-2.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/share.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/share.imageset/share.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/shield.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/shield.imageset/shield.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/smartphone.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/smartphone.imageset/smartphone.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/smile.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/smile.imageset/smile.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/star.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/star.imageset/star.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/trending-up.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/trending-up.imageset/trending-up.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/user-check.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/user-check.imageset/user-check.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/user-x.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/user-x.imageset/user-x.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/user.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/user.imageset/user.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/users.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/users.imageset/users.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/wifi.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/wifi.imageset/wifi.svg +1 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/x.imageset/Contents.json +15 -0
- package/src/components/core/Icon-Base/platforms/ios/Icons.xcassets/Icons/x.imageset/x.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/IconBase.web.ts +553 -0
- package/src/components/core/Icon-Base/platforms/web/assets/alert-circle.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/arrow-down.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/arrow-left.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/arrow-right.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/arrow-up.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/award.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/bell.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/briefcase.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/calendar.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/check-circle.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/check.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/chevron-down.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/chevron-left.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/chevron-right.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/circle.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/clock.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/credit-card.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/dollar-sign.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/external-link.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/eye-off.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/eye.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/file-text.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/filter.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/globe.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/heart.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/info.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/mail.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/map-pin.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/minus.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/more-horizontal.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/more-vertical.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/phone.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/plus.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/refresh-cw.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/save.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/search.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/settings.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/share-2.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/share.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/shield.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/smartphone.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/smile.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/star.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/trending-up.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/user-check.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/user-x.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/user.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/users.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/wifi.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/assets/x.svg +1 -0
- package/src/components/core/Icon-Base/platforms/web/styles.css +203 -0
- package/src/components/core/Icon-Base/types.ts +338 -0
- package/src/components/core/Input-Checkbox-Base/Input-Checkbox-Base.schema.yaml +147 -0
- package/src/components/core/Input-Checkbox-Base/README.md +390 -0
- package/src/components/core/Input-Checkbox-Base/__tests__/InputCheckboxBase.stemma.test.ts +552 -0
- package/src/components/core/Input-Checkbox-Base/__tests__/InputCheckboxBase.test.ts +878 -0
- package/src/components/core/Input-Checkbox-Base/checkbox-sizing.tokens.ts +37 -0
- package/src/components/core/Input-Checkbox-Base/component-meta.yaml +39 -0
- package/src/components/core/Input-Checkbox-Base/contracts.yaml +165 -0
- package/src/components/core/Input-Checkbox-Base/platforms/android/InputCheckboxBase.android.kt +777 -0
- package/src/components/core/Input-Checkbox-Base/platforms/ios/InputCheckboxBase.ios.swift +612 -0
- package/src/components/core/Input-Checkbox-Base/platforms/web/InputCheckboxBase.web.css +477 -0
- package/src/components/core/Input-Checkbox-Base/platforms/web/InputCheckboxBase.web.ts +561 -0
- package/src/components/core/Input-Checkbox-Base/types.ts +399 -0
- package/src/components/core/Input-Checkbox-Legal/Input-Checkbox-Legal.schema.yaml +81 -0
- package/src/components/core/Input-Checkbox-Legal/README.md +554 -0
- package/src/components/core/Input-Checkbox-Legal/__tests__/InputCheckboxLegal.test.ts +727 -0
- package/src/components/core/Input-Checkbox-Legal/component-meta.yaml +39 -0
- package/src/components/core/Input-Checkbox-Legal/contracts.yaml +55 -0
- package/src/components/core/Input-Checkbox-Legal/platforms/android/.gitkeep +2 -0
- package/src/components/core/Input-Checkbox-Legal/platforms/android/InputCheckboxLegal.android.kt +408 -0
- package/src/components/core/Input-Checkbox-Legal/platforms/ios/.gitkeep +2 -0
- package/src/components/core/Input-Checkbox-Legal/platforms/ios/InputCheckboxLegal.ios.swift +387 -0
- package/src/components/core/Input-Checkbox-Legal/platforms/web/InputCheckboxLegal.web.css +112 -0
- package/src/components/core/Input-Checkbox-Legal/platforms/web/InputCheckboxLegal.web.ts +505 -0
- package/src/components/core/Input-Checkbox-Legal/types.ts +348 -0
- package/src/components/core/Input-Radio-Base/.gitkeep +2 -0
- package/src/components/core/Input-Radio-Base/Input-Radio-Base.schema.yaml +139 -0
- package/src/components/core/Input-Radio-Base/README.md +427 -0
- package/src/components/core/Input-Radio-Base/__tests__/.gitkeep +1 -0
- package/src/components/core/Input-Radio-Base/__tests__/InputRadioBase.form.test.ts +299 -0
- package/src/components/core/Input-Radio-Base/__tests__/InputRadioBase.stemma.test.ts +543 -0
- package/src/components/core/Input-Radio-Base/__tests__/InputRadioBase.test.ts +429 -0
- package/src/components/core/Input-Radio-Base/component-meta.yaml +28 -0
- package/src/components/core/Input-Radio-Base/contracts.yaml +140 -0
- package/src/components/core/Input-Radio-Base/platforms/android/InputRadioBase.android.kt +685 -0
- package/src/components/core/Input-Radio-Base/platforms/ios/.gitkeep +1 -0
- package/src/components/core/Input-Radio-Base/platforms/ios/InputRadioBase.ios.swift +567 -0
- package/src/components/core/Input-Radio-Base/platforms/web/.gitkeep +1 -0
- package/src/components/core/Input-Radio-Base/platforms/web/InputRadioBase.web.css +504 -0
- package/src/components/core/Input-Radio-Base/platforms/web/InputRadioBase.web.ts +648 -0
- package/src/components/core/Input-Radio-Base/radio-sizing.tokens.ts +37 -0
- package/src/components/core/Input-Radio-Base/types.ts +362 -0
- package/src/components/core/Input-Radio-Set/Input-Radio-Set.schema.yaml +92 -0
- package/src/components/core/Input-Radio-Set/README.md +373 -0
- package/src/components/core/Input-Radio-Set/__tests__/.gitkeep +0 -0
- package/src/components/core/Input-Radio-Set/__tests__/InputRadioSet.stemma.test.ts +493 -0
- package/src/components/core/Input-Radio-Set/__tests__/InputRadioSet.test.ts +499 -0
- package/src/components/core/Input-Radio-Set/component-meta.yaml +44 -0
- package/src/components/core/Input-Radio-Set/contracts.yaml +100 -0
- package/src/components/core/Input-Radio-Set/platforms/android/.gitkeep +0 -0
- package/src/components/core/Input-Radio-Set/platforms/android/InputRadioSet.android.kt +363 -0
- package/src/components/core/Input-Radio-Set/platforms/ios/InputRadioSet.ios.swift +330 -0
- package/src/components/core/Input-Radio-Set/platforms/web/InputRadioSet.web.css +99 -0
- package/src/components/core/Input-Radio-Set/platforms/web/InputRadioSet.web.ts +790 -0
- package/src/components/core/Input-Radio-Set/types.ts +301 -0
- package/src/components/core/Input-Text-Base/Input-Text-Base.schema.yaml +219 -0
- package/src/components/core/Input-Text-Base/README.md +235 -0
- package/src/components/core/Input-Text-Base/__tests__/focusIndicators.test.ts +310 -0
- package/src/components/core/Input-Text-Base/__tests__/keyboardNavigation.test.ts +444 -0
- package/src/components/core/Input-Text-Base/__tests__/labelAssociation.test.ts +418 -0
- package/src/components/core/Input-Text-Base/__tests__/screenReaderSupport.test.ts +405 -0
- package/src/components/core/Input-Text-Base/__tests__/setup.ts +17 -0
- package/src/components/core/Input-Text-Base/__tests__/stateManagement.test.ts +718 -0
- package/src/components/core/Input-Text-Base/__tests__/test-utils.ts +81 -0
- package/src/components/core/Input-Text-Base/__tests__/touchTargetSizing.test.ts +319 -0
- package/src/components/core/Input-Text-Base/component-meta.yaml +38 -0
- package/src/components/core/Input-Text-Base/contracts.yaml +149 -0
- package/src/components/core/Input-Text-Base/platforms/android/InputTextBase.android.kt +481 -0
- package/src/components/core/Input-Text-Base/platforms/ios/InputTextBase.ios.swift +507 -0
- package/src/components/core/Input-Text-Base/platforms/web/InputTextBase.browser.ts +241 -0
- package/src/components/core/Input-Text-Base/platforms/web/InputTextBase.web.css +293 -0
- package/src/components/core/Input-Text-Base/platforms/web/InputTextBase.web.ts +448 -0
- package/src/components/core/Input-Text-Base/stateManagement.ts +267 -0
- package/src/components/core/Input-Text-Base/tokens.ts +210 -0
- package/src/components/core/Input-Text-Base/types.ts +102 -0
- package/src/components/core/Input-Text-Email/Input-Text-Email.schema.yaml +247 -0
- package/src/components/core/Input-Text-Email/README.md +251 -0
- package/src/components/core/Input-Text-Email/__tests__/validation.test.ts +127 -0
- package/src/components/core/Input-Text-Email/component-meta.yaml +27 -0
- package/src/components/core/Input-Text-Email/contracts.yaml +47 -0
- package/src/components/core/Input-Text-Email/platforms/android/InputTextEmail.android.kt +197 -0
- package/src/components/core/Input-Text-Email/platforms/ios/InputTextEmail.ios.swift +291 -0
- package/src/components/core/Input-Text-Email/platforms/web/InputTextEmail.browser.ts +276 -0
- package/src/components/core/Input-Text-Email/platforms/web/InputTextEmail.web.ts +319 -0
- package/src/components/core/Input-Text-Email/stateManagement.ts +160 -0
- package/src/components/core/Input-Text-Email/tokens.ts +33 -0
- package/src/components/core/Input-Text-Email/types.ts +72 -0
- package/src/components/core/Input-Text-Email/validation.ts +130 -0
- package/src/components/core/Input-Text-Password/Input-Text-Password.schema.yaml +300 -0
- package/src/components/core/Input-Text-Password/README.md +359 -0
- package/src/components/core/Input-Text-Password/__tests__/validation.test.ts +362 -0
- package/src/components/core/Input-Text-Password/component-meta.yaml +28 -0
- package/src/components/core/Input-Text-Password/contracts.yaml +63 -0
- package/src/components/core/Input-Text-Password/platforms/android/InputTextPassword.android.kt +318 -0
- package/src/components/core/Input-Text-Password/platforms/ios/InputTextPassword.ios.swift +446 -0
- package/src/components/core/Input-Text-Password/platforms/web/InputTextPassword.browser.ts +434 -0
- package/src/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.ts +503 -0
- package/src/components/core/Input-Text-Password/stateManagement.ts +244 -0
- package/src/components/core/Input-Text-Password/tokens.ts +32 -0
- package/src/components/core/Input-Text-Password/types.ts +177 -0
- package/src/components/core/Input-Text-Password/validation.ts +207 -0
- package/src/components/core/Input-Text-PhoneNumber/Input-Text-PhoneNumber.schema.yaml +326 -0
- package/src/components/core/Input-Text-PhoneNumber/README.md +275 -0
- package/src/components/core/Input-Text-PhoneNumber/__tests__/validation.test.ts +301 -0
- package/src/components/core/Input-Text-PhoneNumber/component-meta.yaml +28 -0
- package/src/components/core/Input-Text-PhoneNumber/contracts.yaml +62 -0
- package/src/components/core/Input-Text-PhoneNumber/platforms/android/InputTextPhoneNumber.android.kt +315 -0
- package/src/components/core/Input-Text-PhoneNumber/platforms/ios/InputTextPhoneNumber.ios.swift +419 -0
- package/src/components/core/Input-Text-PhoneNumber/platforms/web/InputTextPhoneNumber.browser.ts +370 -0
- package/src/components/core/Input-Text-PhoneNumber/platforms/web/InputTextPhoneNumber.web.ts +393 -0
- package/src/components/core/Input-Text-PhoneNumber/stateManagement.ts +250 -0
- package/src/components/core/Input-Text-PhoneNumber/tokens.ts +33 -0
- package/src/components/core/Input-Text-PhoneNumber/types.ts +135 -0
- package/src/components/core/Input-Text-PhoneNumber/validation.ts +302 -0
- package/src/components/core/Nav-Header-App/Nav-Header-App.schema.yaml +87 -0
- package/src/components/core/Nav-Header-App/README.md +29 -0
- package/src/components/core/Nav-Header-App/component-meta.yaml +19 -0
- package/src/components/core/Nav-Header-App/contracts.yaml +27 -0
- package/src/components/core/Nav-Header-App/index.ts +5 -0
- package/src/components/core/Nav-Header-App/platforms/android/NavHeaderApp.android.kt +28 -0
- package/src/components/core/Nav-Header-App/platforms/ios/NavHeaderApp.ios.swift +27 -0
- package/src/components/core/Nav-Header-App/platforms/web/NavHeaderApp.web.ts +37 -0
- package/src/components/core/Nav-Header-App/types.ts +32 -0
- package/src/components/core/Nav-Header-Base/Nav-Header-Base.schema.yaml +150 -0
- package/src/components/core/Nav-Header-Base/README.md +21 -0
- package/src/components/core/Nav-Header-Base/component-meta.yaml +15 -0
- package/src/components/core/Nav-Header-Base/contracts.yaml +178 -0
- package/src/components/core/Nav-Header-Base/index.ts +12 -0
- package/src/components/core/Nav-Header-Base/platforms/android/NavHeaderBase.android.kt +127 -0
- package/src/components/core/Nav-Header-Base/platforms/ios/NavHeaderBase.ios.swift +99 -0
- package/src/components/core/Nav-Header-Base/platforms/web/NavHeaderBase.styles.css +75 -0
- package/src/components/core/Nav-Header-Base/platforms/web/NavHeaderBase.web.ts +120 -0
- package/src/components/core/Nav-Header-Base/types.ts +63 -0
- package/src/components/core/Nav-Header-Page/Nav-Header-Page.schema.yaml +175 -0
- package/src/components/core/Nav-Header-Page/README.md +34 -0
- package/src/components/core/Nav-Header-Page/__tests__/NavHeaderPage.test.ts +250 -0
- package/src/components/core/Nav-Header-Page/component-meta.yaml +23 -0
- package/src/components/core/Nav-Header-Page/contracts.yaml +196 -0
- package/src/components/core/Nav-Header-Page/index.ts +12 -0
- package/src/components/core/Nav-Header-Page/platforms/android/NavHeaderPage.android.kt +169 -0
- package/src/components/core/Nav-Header-Page/platforms/ios/NavHeaderPage.ios.swift +196 -0
- package/src/components/core/Nav-Header-Page/platforms/web/NavHeaderPage.styles.css +90 -0
- package/src/components/core/Nav-Header-Page/platforms/web/NavHeaderPage.web.ts +169 -0
- package/src/components/core/Nav-Header-Page/types.ts +55 -0
- package/src/components/core/Nav-SegmentedChoice-Base/Nav-SegmentedChoice-Base.schema.yaml +203 -0
- package/src/components/core/Nav-SegmentedChoice-Base/README.md +327 -0
- package/src/components/core/Nav-SegmentedChoice-Base/__tests__/NavSegmentedChoiceBase.android.test.ts +218 -0
- package/src/components/core/Nav-SegmentedChoice-Base/__tests__/NavSegmentedChoiceBase.interaction.test.ts +419 -0
- package/src/components/core/Nav-SegmentedChoice-Base/__tests__/NavSegmentedChoiceBase.ios.test.ts +207 -0
- package/src/components/core/Nav-SegmentedChoice-Base/__tests__/NavSegmentedChoiceBase.visual.test.ts +371 -0
- package/src/components/core/Nav-SegmentedChoice-Base/component-meta.yaml +20 -0
- package/src/components/core/Nav-SegmentedChoice-Base/contracts.yaml +435 -0
- package/src/components/core/Nav-SegmentedChoice-Base/index.ts +38 -0
- package/src/components/core/Nav-SegmentedChoice-Base/platforms/android/NavSegmentedChoiceBase.android.kt +389 -0
- package/src/components/core/Nav-SegmentedChoice-Base/platforms/ios/NavSegmentedChoiceBase.ios.swift +373 -0
- package/src/components/core/Nav-SegmentedChoice-Base/platforms/web/NavSegmentedChoiceBase.styles.css +160 -0
- package/src/components/core/Nav-SegmentedChoice-Base/platforms/web/NavSegmentedChoiceBase.web.ts +477 -0
- package/src/components/core/Nav-SegmentedChoice-Base/types.ts +65 -0
- package/src/components/core/Nav-TabBar-Base/Nav-TabBar-Base.schema.yaml +196 -0
- package/src/components/core/Nav-TabBar-Base/README.md +264 -0
- package/src/components/core/Nav-TabBar-Base/__tests__/NavTabBarBase.android.test.ts +270 -0
- package/src/components/core/Nav-TabBar-Base/__tests__/NavTabBarBase.ios.test.ts +221 -0
- package/src/components/core/Nav-TabBar-Base/__tests__/NavTabBarBase.test.ts +421 -0
- package/src/components/core/Nav-TabBar-Base/component-meta.yaml +20 -0
- package/src/components/core/Nav-TabBar-Base/contracts.yaml +412 -0
- package/src/components/core/Nav-TabBar-Base/examples/BasicUsage.html +2 -0
- package/src/components/core/Nav-TabBar-Base/examples/BasicUsage.tsx +2 -0
- package/src/components/core/Nav-TabBar-Base/index.ts +20 -0
- package/src/components/core/Nav-TabBar-Base/platforms/android/NavTabBarBase.android.kt +375 -0
- package/src/components/core/Nav-TabBar-Base/platforms/ios/NavTabBarBase.ios.swift +377 -0
- package/src/components/core/Nav-TabBar-Base/platforms/web/NavTabBarBase.styles.css +281 -0
- package/src/components/core/Nav-TabBar-Base/platforms/web/NavTabBarBase.web.ts +420 -0
- package/src/components/core/Nav-TabBar-Base/types.ts +43 -0
- package/src/components/core/Progress-Bar-Base/Progress-Bar-Base.schema.yaml +101 -0
- package/src/components/core/Progress-Bar-Base/README.md +31 -0
- package/src/components/core/Progress-Bar-Base/__tests__/ProgressBarBase.test.ts +202 -0
- package/src/components/core/Progress-Bar-Base/component-meta.yaml +24 -0
- package/src/components/core/Progress-Bar-Base/contracts.yaml +132 -0
- package/src/components/core/Progress-Bar-Base/index.ts +6 -0
- package/src/components/core/Progress-Bar-Base/platforms/android/ProgressBarBase.android.kt +181 -0
- package/src/components/core/Progress-Bar-Base/platforms/ios/ProgressBarBase.ios.swift +141 -0
- package/src/components/core/Progress-Bar-Base/platforms/web/ProgressBarBase.styles.css +52 -0
- package/src/components/core/Progress-Bar-Base/platforms/web/ProgressBarBase.web.ts +135 -0
- package/src/components/core/Progress-Bar-Base/types.ts +46 -0
- package/src/components/core/Progress-Indicator-Connector-Base/Progress-Indicator-Connector-Base.schema.yaml +69 -0
- package/src/components/core/Progress-Indicator-Connector-Base/README.md +169 -0
- package/src/components/core/Progress-Indicator-Connector-Base/component-meta.yaml +18 -0
- package/src/components/core/Progress-Indicator-Connector-Base/contracts.yaml +70 -0
- package/src/components/core/Progress-Indicator-Connector-Base/index.ts +33 -0
- package/src/components/core/Progress-Indicator-Connector-Base/platforms/android/ProgressIndicatorConnectorBase.android.kt +163 -0
- package/src/components/core/Progress-Indicator-Connector-Base/platforms/ios/ProgressIndicatorConnectorBase.ios.swift +154 -0
- package/src/components/core/Progress-Indicator-Connector-Base/platforms/web/ProgressIndicatorConnectorBase.styles.css +50 -0
- package/src/components/core/Progress-Indicator-Connector-Base/platforms/web/ProgressIndicatorConnectorBase.web.ts +141 -0
- package/src/components/core/Progress-Indicator-Connector-Base/types.ts +67 -0
- package/src/components/core/Progress-Indicator-Label-Base/Progress-Indicator-Label-Base.schema.yaml +78 -0
- package/src/components/core/Progress-Indicator-Label-Base/README.md +191 -0
- package/src/components/core/Progress-Indicator-Label-Base/component-meta.yaml +18 -0
- package/src/components/core/Progress-Indicator-Label-Base/contracts.yaml +76 -0
- package/src/components/core/Progress-Indicator-Label-Base/index.ts +28 -0
- package/src/components/core/Progress-Indicator-Label-Base/platforms/android/ProgressIndicatorLabelBase.android.kt +153 -0
- package/src/components/core/Progress-Indicator-Label-Base/platforms/ios/ProgressIndicatorLabelBase.ios.swift +153 -0
- package/src/components/core/Progress-Indicator-Label-Base/platforms/web/ProgressIndicatorLabelBase.styles.css +81 -0
- package/src/components/core/Progress-Indicator-Label-Base/platforms/web/ProgressIndicatorLabelBase.web.ts +174 -0
- package/src/components/core/Progress-Indicator-Label-Base/types.ts +64 -0
- package/src/components/core/Progress-Indicator-Node-Base/Progress-Indicator-Node-Base.schema.yaml +113 -0
- package/src/components/core/Progress-Indicator-Node-Base/README.md +206 -0
- package/src/components/core/Progress-Indicator-Node-Base/__tests__/VisualStates.test.ts +259 -0
- package/src/components/core/Progress-Indicator-Node-Base/component-meta.yaml +18 -0
- package/src/components/core/Progress-Indicator-Node-Base/contracts.yaml +96 -0
- package/src/components/core/Progress-Indicator-Node-Base/index.ts +36 -0
- package/src/components/core/Progress-Indicator-Node-Base/platforms/android/ProgressIndicatorNodeBase.android.kt +294 -0
- package/src/components/core/Progress-Indicator-Node-Base/platforms/ios/ProgressIndicatorNodeBase.ios.swift +260 -0
- package/src/components/core/Progress-Indicator-Node-Base/platforms/web/ProgressIndicatorNodeBase.styles.css +193 -0
- package/src/components/core/Progress-Indicator-Node-Base/platforms/web/ProgressIndicatorNodeBase.web.ts +226 -0
- package/src/components/core/Progress-Indicator-Node-Base/types.ts +142 -0
- package/src/components/core/Progress-Pagination-Base/Progress-Pagination-Base.schema.yaml +106 -0
- package/src/components/core/Progress-Pagination-Base/README.md +290 -0
- package/src/components/core/Progress-Pagination-Base/__tests__/PaginationBase.test.ts +290 -0
- package/src/components/core/Progress-Pagination-Base/component-meta.yaml +22 -0
- package/src/components/core/Progress-Pagination-Base/contracts.yaml +103 -0
- package/src/components/core/Progress-Pagination-Base/index.ts +40 -0
- package/src/components/core/Progress-Pagination-Base/platforms/android/ProgressPaginationBase.android.kt +215 -0
- package/src/components/core/Progress-Pagination-Base/platforms/ios/ProgressPaginationBase.ios.swift +214 -0
- package/src/components/core/Progress-Pagination-Base/platforms/web/ProgressPaginationBase.styles.css +80 -0
- package/src/components/core/Progress-Pagination-Base/platforms/web/ProgressPaginationBase.web.ts +293 -0
- package/src/components/core/Progress-Pagination-Base/types.ts +112 -0
- package/src/components/core/Progress-Stepper-Base/Progress-Stepper-Base.schema.yaml +105 -0
- package/src/components/core/Progress-Stepper-Base/README.md +311 -0
- package/src/components/core/Progress-Stepper-Base/__tests__/StepperBase.test.ts +342 -0
- package/src/components/core/Progress-Stepper-Base/component-meta.yaml +22 -0
- package/src/components/core/Progress-Stepper-Base/contracts.yaml +101 -0
- package/src/components/core/Progress-Stepper-Base/index.ts +43 -0
- package/src/components/core/Progress-Stepper-Base/platforms/android/ProgressStepperBase.android.kt +244 -0
- package/src/components/core/Progress-Stepper-Base/platforms/ios/ProgressStepperBase.ios.swift +240 -0
- package/src/components/core/Progress-Stepper-Base/platforms/web/ProgressStepperBase.styles.css +49 -0
- package/src/components/core/Progress-Stepper-Base/platforms/web/ProgressStepperBase.web.ts +288 -0
- package/src/components/core/Progress-Stepper-Base/types.ts +175 -0
- package/src/components/core/Progress-Stepper-Detailed/Progress-Stepper-Detailed.schema.yaml +107 -0
- package/src/components/core/Progress-Stepper-Detailed/README.md +401 -0
- package/src/components/core/Progress-Stepper-Detailed/__tests__/StepperDetailed.test.ts +478 -0
- package/src/components/core/Progress-Stepper-Detailed/component-meta.yaml +22 -0
- package/src/components/core/Progress-Stepper-Detailed/contracts.yaml +122 -0
- package/src/components/core/Progress-Stepper-Detailed/index.ts +48 -0
- package/src/components/core/Progress-Stepper-Detailed/platforms/android/ProgressStepperDetailed.android.kt +352 -0
- package/src/components/core/Progress-Stepper-Detailed/platforms/ios/ProgressStepperDetailed.ios.swift +353 -0
- package/src/components/core/Progress-Stepper-Detailed/platforms/web/ProgressStepperDetailed.styles.css +106 -0
- package/src/components/core/Progress-Stepper-Detailed/platforms/web/ProgressStepperDetailed.web.ts +336 -0
- package/src/components/core/Progress-Stepper-Detailed/types.ts +195 -0
- package/src/composition/BlendComposition.ts +46 -0
- package/src/composition/BlendCompositionParser.ts +215 -0
- package/src/composition/OpacityComposition.ts +62 -0
- package/src/composition/OpacityCompositionParser.ts +308 -0
- package/src/composition/__tests__/BlendCompositionParser.test.ts +431 -0
- package/src/composition/__tests__/OpacityCompositionParser.test.ts +539 -0
- package/src/composition/index.ts +20 -0
- package/src/config/ConfigLoader.ts +143 -0
- package/src/config/__resolution-matrix__/README.md +76 -0
- package/src/config/__resolution-matrix__/fixtures/faithful-cjs/compiled/defineConfig.js +9 -0
- package/src/config/__resolution-matrix__/fixtures/faithful-cjs/designerpunk.config.ts +20 -0
- package/src/config/__resolution-matrix__/fixtures/faithful-cjs/my-overrides.ts +8 -0
- package/src/config/__resolution-matrix__/fixtures/faithful-esm/compiled/defineConfig.js +11 -0
- package/src/config/__resolution-matrix__/fixtures/faithful-esm/designerpunk.config.ts +23 -0
- package/src/config/__resolution-matrix__/fixtures/faithful-esm/my-overrides.ts +6 -0
- package/src/config/__resolution-matrix__/fixtures/source-dir-cjs/designerpunk.config.ts +11 -0
- package/src/config/__resolution-matrix__/fixtures/source-dir-cjs/src/config/index.ts +15 -0
- package/src/config/__resolution-matrix__/fixtures/source-dir-esm/designerpunk.config.ts +15 -0
- package/src/config/__resolution-matrix__/fixtures/source-dir-esm/src/config/index.ts +13 -0
- package/src/config/__resolution-matrix__/run-matrix.js +107 -0
- package/src/config/__resolution-matrix__/runner.js +153 -0
- package/src/config/__resolution-matrix__/verify-real-loadconfig.js +122 -0
- package/src/config/__tests__/ConfigLoader.test.ts +115 -0
- package/src/config/defineConfig.ts +71 -0
- package/src/config/index.ts +7 -0
- package/src/config/scopedTsRequire.ts +62 -0
- package/src/constants/BaselineGrid.ts +41 -0
- package/src/constants/SpacingTokens.ts +55 -0
- package/src/constants/StrategicFlexibilityTokens.ts +98 -0
- package/src/figma/ComponentAnalysis.ts +292 -0
- package/src/figma/ComponentAnalysisGenerator.ts +444 -0
- package/src/figma/ConsoleMCPClient.ts +168 -0
- package/src/figma/ConsoleMCPClientImpl.ts +1034 -0
- package/src/figma/DesignExtractor.ts +3620 -0
- package/src/figma/TokenSyncWorkflow.ts +915 -0
- package/src/figma/TokenTranslator.ts +891 -0
- package/src/figma/VariantAnalyzer.ts +712 -0
- package/src/figma/__tests__/ComponentAnalysisGenerator.json.test.ts +429 -0
- package/src/figma/__tests__/ComponentAnalysisGenerator.markdown.test.ts +428 -0
- package/src/figma/__tests__/ConsoleMCPClient.bugfix.test.ts +261 -0
- package/src/figma/__tests__/ConsoleMCPClient.preservation.test.ts +395 -0
- package/src/figma/__tests__/ConsoleMCPClient.test.ts +375 -0
- package/src/figma/__tests__/DesignExtractor.boundVariableResolution.test.ts +580 -0
- package/src/figma/__tests__/DesignExtractor.buildNodeTree.test.ts +535 -0
- package/src/figma/__tests__/DesignExtractor.captureComponentScreenshot.test.ts +176 -0
- package/src/figma/__tests__/DesignExtractor.detectBehavioralContracts.test.ts +263 -0
- package/src/figma/__tests__/DesignExtractor.detectComponentTokenDecisions.test.ts +379 -0
- package/src/figma/__tests__/DesignExtractor.detectCompositionPatterns.test.ts +507 -0
- package/src/figma/__tests__/DesignExtractor.detectPlatformParity.test.ts +406 -0
- package/src/figma/__tests__/DesignExtractor.queryContext.test.ts +214 -0
- package/src/figma/__tests__/DesignExtractor.readFigmaComponent.test.ts +431 -0
- package/src/figma/__tests__/DesignExtractor.readStyles.test.ts +204 -0
- package/src/figma/__tests__/DesignExtractor.readTokenBindings.test.ts +268 -0
- package/src/figma/__tests__/DesignExtractor.reconstructCompositeTokens.test.ts +403 -0
- package/src/figma/__tests__/DesignExtractor.resolveUnknownVariableIds.test.ts +259 -0
- package/src/figma/__tests__/DesignExtractor.translateTokens.test.ts +433 -0
- package/src/figma/__tests__/DesignExtractor.validateModes.test.ts +350 -0
- package/src/figma/__tests__/TokenSyncWorkflow.batch.test.ts +277 -0
- package/src/figma/__tests__/TokenSyncWorkflow.drift.test.ts +187 -0
- package/src/figma/__tests__/TokenSyncWorkflow.preservation.test.ts +544 -0
- package/src/figma/__tests__/TokenSyncWorkflow.styles.test.ts +245 -0
- package/src/figma/__tests__/TokenSyncWorkflow.sync.test.ts +217 -0
- package/src/figma/__tests__/TokenTranslator.test.ts +757 -0
- package/src/figma/__tests__/VariantAnalyzer.detectConflicts.test.ts +126 -0
- package/src/figma/__tests__/VariantAnalyzer.test.ts +633 -0
- package/src/figma/__tests__/error-reporting.test.ts +254 -0
- package/src/figma/__tests__/preflight.test.ts +94 -0
- package/src/figma/error-reporting.ts +260 -0
- package/src/figma/index.ts +98 -0
- package/src/figma/portCleanup.ts +86 -0
- package/src/figma/preflight.ts +120 -0
- package/src/generators/BlendUtilityGenerator.ts +847 -0
- package/src/generators/BlendValueGenerator.ts +198 -0
- package/src/generators/DTCGFormatGenerator.ts +1349 -0
- package/src/generators/DTCGGeneratorConfig.ts +46 -0
- package/src/generators/ModeResolvedTokens.ts +58 -0
- package/src/generators/ResponsiveGridGenerator.ts +273 -0
- package/src/generators/TokenFileGenerator.ts +2070 -0
- package/src/generators/__tests__/AccessibilityTokenGeneration.test.ts +350 -0
- package/src/generators/__tests__/BlendUtilityGenerator.test.ts +829 -0
- package/src/generators/__tests__/BlendValueGenerator.test.ts +200 -0
- package/src/generators/__tests__/BreakpointTokenGeneration.test.ts +172 -0
- package/src/generators/__tests__/CSSThemeScoping.test.ts +153 -0
- package/src/generators/__tests__/DTCGConfigOptions.test.ts +262 -0
- package/src/generators/__tests__/DTCGErrorHandling.test.ts +139 -0
- package/src/generators/__tests__/DTCGFormatGenerator.integration.test.ts +346 -0
- package/src/generators/__tests__/DTCGFormatGenerator.property.test.ts +497 -0
- package/src/generators/__tests__/DTCGFormatGenerator.test.ts +469 -0
- package/src/generators/__tests__/FigmaTransformer.styles.test.ts +398 -0
- package/src/generators/__tests__/FigmaTransformer.variables.test.ts +540 -0
- package/src/generators/__tests__/GridSpacingTokenGeneration.test.ts +254 -0
- package/src/generators/__tests__/IconTokenGeneration.test.ts +452 -0
- package/src/generators/__tests__/KotlinThemeTypes.test.ts +110 -0
- package/src/generators/__tests__/ModeAwareGeneration.test.ts +160 -0
- package/src/generators/__tests__/NativeOklchOutput.test.ts +56 -0
- package/src/generators/__tests__/OklchExport.test.ts +71 -0
- package/src/generators/__tests__/ProductRepoSimulation.test.ts +91 -0
- package/src/generators/__tests__/ResponsiveGridGeneration.test.ts +291 -0
- package/src/generators/__tests__/Spec076TokenMigration.test.ts +106 -0
- package/src/generators/__tests__/Spec077ModesVerification.test.ts +52 -0
- package/src/generators/__tests__/SwiftThemeTypes.test.ts +122 -0
- package/src/generators/__tests__/TokenFileGenerator.test.ts +914 -0
- package/src/generators/__tests__/TransformerRegistry.test.ts +118 -0
- package/src/generators/__tests__/WcagValueExportSupport.test.ts +84 -0
- package/src/generators/__tests__/WcagValueInfrastructure.test.ts +122 -0
- package/src/generators/__tests__/WebOklchOutput.test.ts +72 -0
- package/src/generators/__tests__/generateTokenIndex.test.ts +204 -0
- package/src/generators/__tests__/helpers/defaultSemanticOptions.ts +24 -0
- package/src/generators/generateTokenFiles.ts +337 -0
- package/src/generators/generateTokenIndex.ts +258 -0
- package/src/generators/oklch/OklchExportUtils.ts +57 -0
- package/src/generators/oklch/OklchTokenIndexMetadata.ts +30 -0
- package/src/generators/transformers/FigmaTransformer.ts +912 -0
- package/src/generators/transformers/ITokenTransformer.ts +56 -0
- package/src/generators/transformers/TransformerRegistry.ts +63 -0
- package/src/generators/transformers/index.ts +52 -0
- package/src/generators/types/DTCGTypes.ts +101 -0
- package/src/integration/BuildErrorHandler.ts +440 -0
- package/src/integration/BuildSystemInterface.ts +338 -0
- package/src/integration/PlatformFileSelector.ts +288 -0
- package/src/integration/RegistryCoordinator.ts +404 -0
- package/src/integration/TranslationCoordinator.ts +458 -0
- package/src/integration/TreeShakingOptimizer.ts +350 -0
- package/src/integration/ValidationCoordinator.ts +780 -0
- package/src/integration/__tests__/ComponentTokenValidation.test.ts +762 -0
- package/src/integration/__tests__/ValidationCoordinator.test.ts +609 -0
- package/src/integration/__tests__/performance/ComponentTokenValidationPerformance.test.ts +161 -0
- package/src/integration/index.ts +55 -0
- package/src/naming/NamingConventionManager.ts +318 -0
- package/src/naming/PlatformNamingRules.ts +278 -0
- package/src/naming/__tests__/NamingConventions.test.ts +224 -0
- package/src/naming/index.ts +23 -0
- package/src/parent-completion.md +1 -0
- package/src/performance/CachingStrategy.ts +426 -0
- package/src/performance/FileGenerationOptimizer.ts +294 -0
- package/src/performance/PerformanceMonitor.ts +185 -0
- package/src/performance/PerformanceOptimizer.ts +348 -0
- package/src/performance/index.ts +30 -0
- package/src/providers/AndroidFileOrganizer.ts +241 -0
- package/src/providers/AndroidFormatGenerator.ts +750 -0
- package/src/providers/AndroidUnitConverter.ts +177 -0
- package/src/providers/FormatProvider.ts +187 -0
- package/src/providers/PathProvider.ts +197 -0
- package/src/providers/UnitProvider.ts +106 -0
- package/src/providers/WebFileOrganizer.ts +121 -0
- package/src/providers/WebFormatGenerator.ts +611 -0
- package/src/providers/WebUnitConverter.ts +116 -0
- package/src/providers/__tests__/AndroidAccessibilityTokens.test.ts +86 -0
- package/src/providers/__tests__/AndroidFormatGenerator-semantic.test.ts +494 -0
- package/src/providers/__tests__/FormatProviders.test.ts +828 -0
- package/src/providers/__tests__/InsetTokenGeneration.test.ts +627 -0
- package/src/providers/__tests__/PathProviders.test.ts +512 -0
- package/src/providers/__tests__/PlatformOutputFormat.test.ts +252 -0
- package/src/providers/__tests__/UnitProviders.test.ts +721 -0
- package/src/providers/__tests__/WebFormatGenerator-semantic.test.ts +293 -0
- package/src/providers/__tests__/iOSFormatGenerator-semantic.test.ts +410 -0
- package/src/providers/iOSFileOrganizer.ts +162 -0
- package/src/providers/iOSFormatGenerator.ts +599 -0
- package/src/providers/iOSUnitConverter.ts +125 -0
- package/src/providers/index.ts +26 -0
- package/src/registries/ComponentTokenRegistry.ts +292 -0
- package/src/registries/IRegistry.ts +170 -0
- package/src/registries/PrimitiveTokenRegistry.ts +200 -0
- package/src/registries/SemanticTokenRegistry.ts +237 -0
- package/src/registries/__tests__/ComponentTokenRegistry.test.ts +446 -0
- package/src/registries/__tests__/IRegistry.test.ts +250 -0
- package/src/registries/__tests__/PrimitiveTokenRegistry.test.ts +342 -0
- package/src/registries/__tests__/SemanticTokenRegistry.test.ts +444 -0
- package/src/resolvers/AndroidColorResolver.ts +333 -0
- package/src/resolvers/ModeThemeResolver.ts +152 -0
- package/src/resolvers/SemanticOverrideResolver.ts +155 -0
- package/src/resolvers/SemanticValueResolver.ts +133 -0
- package/src/resolvers/WebColorResolver.ts +240 -0
- package/src/resolvers/__tests__/AndroidColorResolver.test.ts +507 -0
- package/src/resolvers/__tests__/ModeThemeResolver.test.ts +411 -0
- package/src/resolvers/__tests__/SemanticOverrideResolver.test.ts +186 -0
- package/src/resolvers/__tests__/WebColorResolver.test.ts +405 -0
- package/src/resolvers/__tests__/iOSColorResolver.test.ts +432 -0
- package/src/resolvers/iOSColorResolver.ts +224 -0
- package/src/resolvers/index.ts +11 -0
- package/src/security/AIAgentRestrictions.ts +298 -0
- package/src/security/ContaminationAuditor.ts +393 -0
- package/src/security/ContaminationPrevention.ts +275 -0
- package/src/security/DocumentationGuard.ts +258 -0
- package/src/security/FlexibilityTokenGuard.ts +256 -0
- package/src/security/HumanApprovalWorkflow.ts +319 -0
- package/src/security/__tests__/AIAgentRestrictions.test.ts +482 -0
- package/src/security/__tests__/ContaminationPrevention.test.ts +424 -0
- package/src/security/__tests__/SecurityIntegration.test.ts +505 -0
- package/src/security/index.ts +48 -0
- package/src/styles/responsive-grid-usage.md +992 -0
- package/src/styles/responsive-grid.css +200 -0
- package/src/testing/__tests__/utilities.test.ts +175 -0
- package/src/testing/index.ts +154 -0
- package/src/testing/jest-preset.ts +62 -0
- package/src/testing/style-mock.ts +7 -0
- package/src/testing/validators.ts +10 -0
- package/src/themes/ResolvedThemeSet.ts +22 -0
- package/src/themes/ThemeRegistry.ts +97 -0
- package/src/themes/__tests__/ThemeRegistry.test.ts +162 -0
- package/src/tokens/BlendTokens.ts +132 -0
- package/src/tokens/BlurTokens.ts +154 -0
- package/src/tokens/BorderWidthTokens.ts +101 -0
- package/src/tokens/BreakpointTokens.ts +101 -0
- package/src/tokens/ColorTokens.ts +2162 -0
- package/src/tokens/DensityTokens.ts +119 -0
- package/src/tokens/DurationTokens.ts +111 -0
- package/src/tokens/EasingTokens.ts +163 -0
- package/src/tokens/FontFamilyTokens.ts +95 -0
- package/src/tokens/FontSizeTokens.ts +197 -0
- package/src/tokens/FontWeightTokens.ts +166 -0
- package/src/tokens/GlowOpacityTokens.ts +113 -0
- package/src/tokens/LetterSpacingTokens.ts +114 -0
- package/src/tokens/LineHeightTokens.ts +200 -0
- package/src/tokens/OpacityTokens.ts +233 -0
- package/src/tokens/RadiusTokens.ts +236 -0
- package/src/tokens/ScaleTokens.ts +167 -0
- package/src/tokens/ShadowOffsetTokens.ts +279 -0
- package/src/tokens/ShadowOpacityTokens.ts +118 -0
- package/src/tokens/SizingTokens.ts +221 -0
- package/src/tokens/SpacingTokens.ts +255 -0
- package/src/tokens/TapAreaTokens.ts +124 -0
- package/src/tokens/__tests__/AIReadableMathematicalRelationships.test.ts +298 -0
- package/src/tokens/__tests__/BlendTokens.test.ts +357 -0
- package/src/tokens/__tests__/BlurTokens.test.ts +109 -0
- package/src/tokens/__tests__/BorderWidthTokens.test.ts +394 -0
- package/src/tokens/__tests__/ColorTokens.test.ts +847 -0
- package/src/tokens/__tests__/FontFamilyTokens.test.ts +308 -0
- package/src/tokens/__tests__/FontSizeTokensFormulaValidation.test.ts +176 -0
- package/src/tokens/__tests__/FontWeightTokens.test.ts +336 -0
- package/src/tokens/__tests__/LetterSpacingTokens.test.ts +359 -0
- package/src/tokens/__tests__/LineHeightTokensFormulaValidation.test.ts +235 -0
- package/src/tokens/__tests__/MotionTokens.property.test.ts +638 -0
- package/src/tokens/__tests__/MotionTokens.test.ts +431 -0
- package/src/tokens/__tests__/OpacityTokens.test.ts +370 -0
- package/src/tokens/__tests__/ProgressTokenCompliance.test.ts +163 -0
- package/src/tokens/__tests__/ProgressTokenFormulas.test.ts +93 -0
- package/src/tokens/__tests__/ProgressTokenTranslation.test.ts +170 -0
- package/src/tokens/__tests__/RadiusStrategicFlexibilityValidation.test.ts +133 -0
- package/src/tokens/__tests__/RadiusTokensFormulaValidation.test.ts +240 -0
- package/src/tokens/__tests__/ShadowOffsetTokens.test.ts +407 -0
- package/src/tokens/__tests__/SizingTokens.test.ts +132 -0
- package/src/tokens/__tests__/SpacingTokensFormulaValidation.test.ts +205 -0
- package/src/tokens/__tests__/TokenCategories.test.ts +602 -0
- package/src/tokens/__tests__/chromatic-channels.test.ts +57 -0
- package/src/tokens/__tests__/composed-colors.test.ts +62 -0
- package/src/tokens/__tests__/neutral-partition.test.ts +119 -0
- package/src/tokens/__tests__/portability-boundary.test.ts +60 -0
- package/src/tokens/color/channels/chroma/chromatic.ts +67 -0
- package/src/tokens/color/channels/chroma/neutral.ts +35 -0
- package/src/tokens/color/channels/hues.ts +29 -0
- package/src/tokens/color/channels/index.ts +21 -0
- package/src/tokens/color/channels/lightness/chromatic.ts +68 -0
- package/src/tokens/color/channels/lightness/neutral.ts +36 -0
- package/src/tokens/color/index.ts +31 -0
- package/src/tokens/color/primitives/chromatic.ts +64 -0
- package/src/tokens/color/primitives/neutral.ts +45 -0
- package/src/tokens/component/progress.ts +153 -0
- package/src/tokens/index.ts +383 -0
- package/src/tokens/platforms/android/MotionTokens.kt +322 -0
- package/src/tokens/platforms/android/MotionTokens.md +0 -0
- package/src/tokens/platforms/ios/MotionTokens.md +322 -0
- package/src/tokens/platforms/ios/MotionTokens.swift +253 -0
- package/src/tokens/semantic/AccessibilityTokens.README.md +1070 -0
- package/src/tokens/semantic/AccessibilityTokens.ts +219 -0
- package/src/tokens/semantic/BlendTokens.ts +225 -0
- package/src/tokens/semantic/BorderWidthTokens.ts +162 -0
- package/src/tokens/semantic/ColorTokens.ts +866 -0
- package/src/tokens/semantic/ElevationTokens.ts +177 -0
- package/src/tokens/semantic/GridSpacingTokens.ts +147 -0
- package/src/tokens/semantic/IconTokens.ts +342 -0
- package/src/tokens/semantic/LayeringTokens.ts +167 -0
- package/src/tokens/semantic/MotionTokens.ts +143 -0
- package/src/tokens/semantic/OpacityTokens.ts +89 -0
- package/src/tokens/semantic/RadiusTokens.ts +242 -0
- package/src/tokens/semantic/ShadowTokens.ts +442 -0
- package/src/tokens/semantic/SpacingTokens.ts +274 -0
- package/src/tokens/semantic/StyleTokens.ts +22 -0
- package/src/tokens/semantic/TypographyTokens.ts +399 -0
- package/src/tokens/semantic/ZIndexTokens.ts +124 -0
- package/src/tokens/semantic/__tests__/AccessibilityTokens.test.ts +222 -0
- package/src/tokens/semantic/__tests__/BlendTokens.test.ts +377 -0
- package/src/tokens/semantic/__tests__/BorderWidthTokens.test.ts +141 -0
- package/src/tokens/semantic/__tests__/ColorTokens.test.ts +1391 -0
- package/src/tokens/semantic/__tests__/IconTokens.test.ts +769 -0
- package/src/tokens/semantic/__tests__/MotionTokens.test.ts +313 -0
- package/src/tokens/semantic/__tests__/OpacityTokens.test.ts +183 -0
- package/src/tokens/semantic/__tests__/SemanticTokenIntegration.test.ts +426 -0
- package/src/tokens/semantic/__tests__/ValidatePrimitiveReferences.test.ts +382 -0
- package/src/tokens/semantic/index.ts +611 -0
- package/src/tokens/themes/dark/SemanticOverrides.ts +168 -0
- package/src/tokens/themes/dark-wcag/SemanticOverrides.ts +21 -0
- package/src/tokens/themes/types.ts +26 -0
- package/src/tokens/themes/wcag/SemanticOverrides.ts +28 -0
- package/src/tools/ThemeFileGenerator.ts +109 -0
- package/src/tools/integrity/DiskFreshGenerator.ts +36 -0
- package/src/tools/integrity/GenerationIntegrityCheck.ts +132 -0
- package/src/tools/integrity/Invariants.ts +228 -0
- package/src/tools/integrity/Normalizer.ts +94 -0
- package/src/tools/integrity/SemanticComparator.ts +127 -0
- package/src/tools/integrity/__tests__/GenerationIntegrityCheck.test.ts +132 -0
- package/src/tools/integrity/__tests__/Invariants.test.ts +142 -0
- package/src/tools/integrity/__tests__/Normalizer.test.ts +65 -0
- package/src/tools/integrity/__tests__/SemanticComparator.test.ts +62 -0
- package/src/tools/integrity/__tests__/consumer-package-mode.test.ts +205 -0
- package/src/tools/integrity/cli/run-audit.ts +150 -0
- package/src/tools/integrity/inventory.ts +51 -0
- package/src/tools/integrity/manifest.ts +56 -0
- package/src/tools/integrity/types/index.ts +183 -0
- package/src/tools/release/__tests__/ChangeClassifier.test.ts +133 -0
- package/src/tools/release/__tests__/ChangeExtractor.test.ts +222 -0
- package/src/tools/release/__tests__/GitHubPublisher.test.ts +240 -0
- package/src/tools/release/__tests__/NotesRenderer.test.ts +142 -0
- package/src/tools/release/__tests__/NpmPublisher.test.ts +289 -0
- package/src/tools/release/__tests__/PipelineIntegration.test.ts +188 -0
- package/src/tools/release/__tests__/ReleasePipeline.test.ts +192 -0
- package/src/tools/release/__tests__/SemanticVersionValidator.test.ts +49 -0
- package/src/tools/release/__tests__/SummaryScanner.test.ts +141 -0
- package/src/tools/release/__tests__/TagResolver.test.ts +91 -0
- package/src/tools/release/__tests__/VersionCalculator.test.ts +270 -0
- package/src/tools/release/__tests__/helpers/NpmMockHelper.ts +80 -0
- package/src/tools/release/cli/ReleasePipeline.ts +165 -0
- package/src/tools/release/cli/release-tool.ts +107 -0
- package/src/tools/release/pipeline/ChangeClassifier.ts +61 -0
- package/src/tools/release/pipeline/ChangeExtractor.ts +87 -0
- package/src/tools/release/pipeline/NotesRenderer.ts +66 -0
- package/src/tools/release/pipeline/SummaryScanner.ts +70 -0
- package/src/tools/release/pipeline/TagResolver.ts +40 -0
- package/src/tools/release/pipeline/VersionCalculator.ts +375 -0
- package/src/tools/release/publishers/GitHubPublisher.ts +228 -0
- package/src/tools/release/publishers/NpmPublisher.ts +196 -0
- package/src/tools/release/release-config.json +5 -0
- package/src/tools/release/types/index.ts +282 -0
- package/src/tools/release/validators/SemanticVersionValidator.ts +67 -0
- package/src/types/ComponentTypes.ts +76 -0
- package/src/types/PrimitiveToken.ts +112 -0
- package/src/types/SemanticToken.ts +91 -0
- package/src/types/TranslationOutput.ts +105 -0
- package/src/types/ValidationResult.ts +74 -0
- package/src/types/__tests__/ComponentTypes.test.ts +73 -0
- package/src/types/css.d.ts +35 -0
- package/src/types/generated/TokenTypes.ts +142 -0
- package/src/types/index.ts +42 -0
- package/src/validators/BaselineGridValidator.ts +119 -0
- package/src/validators/CompositionPatternValidator.ts +259 -0
- package/src/validators/CrossPlatformConsistencyValidator.ts +498 -0
- package/src/validators/ErrorValidator.ts +998 -0
- package/src/validators/IValidator.ts +273 -0
- package/src/validators/MathematicalRelationshipParser.ts +434 -0
- package/src/validators/ModeParity.ts +123 -0
- package/src/validators/PassValidator.ts +533 -0
- package/src/validators/PlatformConstraintHandler.ts +453 -0
- package/src/validators/PrimitiveReferenceValidator.ts +284 -0
- package/src/validators/SemanticTokenValidator.ts +496 -0
- package/src/validators/StemmaComponentNamingValidator.ts +524 -0
- package/src/validators/StemmaErrorGuidanceSystem.ts +1600 -0
- package/src/validators/StemmaPropertyAccessibilityValidator.ts +823 -0
- package/src/validators/StemmaTokenUsageValidator.ts +650 -0
- package/src/validators/SyntaxValidator.ts +537 -0
- package/src/validators/ThreeTierValidator.ts +822 -0
- package/src/validators/ToleranceCalculator.ts +324 -0
- package/src/validators/ValidationReasoning.ts +464 -0
- package/src/validators/WCAGValidator.ts +219 -0
- package/src/validators/WarningValidator.ts +626 -0
- package/src/validators/__tests__/BaselineGridValidator.test.ts +292 -0
- package/src/validators/__tests__/BorderWidthValidation.test.ts +595 -0
- package/src/validators/__tests__/CompositionPatterns.test.ts +463 -0
- package/src/validators/__tests__/CrossPlatformConsistency.test.ts +834 -0
- package/src/validators/__tests__/IValidator.test.ts +258 -0
- package/src/validators/__tests__/MathematicalRelationshipParser.test.ts +465 -0
- package/src/validators/__tests__/PlatformConstraints.test.ts +486 -0
- package/src/validators/__tests__/SemanticTokenValidator.test.ts +723 -0
- package/src/validators/__tests__/StemmaComponentNamingValidator.test.ts +597 -0
- package/src/validators/__tests__/StemmaErrorGuidanceSystem.test.ts +717 -0
- package/src/validators/__tests__/StemmaPropertyAccessibilityValidator.test.ts +349 -0
- package/src/validators/__tests__/StemmaTokenUsageValidator.test.ts +432 -0
- package/src/validators/__tests__/SyntaxValidator.test.ts +360 -0
- package/src/validators/__tests__/ThreeTierValidator.test.ts +906 -0
- package/src/validators/__tests__/ValidationReasoning.test.ts +636 -0
- package/src/validators/__tests__/WCAGValidator.test.ts +243 -0
- package/src/validators/buildValidation.ts +170 -0
- package/src/validators/index.ts +144 -0
- package/src/workflows/ConsistencyValidator.ts +339 -0
- package/src/workflows/TokenGenerationWorkflow.ts +460 -0
- package/src/workflows/ValidationPipeline.ts +284 -0
- package/src/workflows/WorkflowErrorHandler.ts +441 -0
- package/token-index/README.md +32 -0
- package/token-index/components.yaml +265 -0
- package/token-index/primitives.yaml +2761 -0
- package/token-index/semantics.yaml +2421 -0
|
@@ -0,0 +1,2838 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* DesignExtractor — Reads Figma designs via dual-MCP strategy and generates
|
|
4
|
+
* design-outline.md documents with confidence flags.
|
|
5
|
+
*
|
|
6
|
+
* Uses Kiro Figma Power for rich design context and figma-console-mcp for
|
|
7
|
+
* variable/style data. Orchestrates TokenTranslator for value matching and
|
|
8
|
+
* VariantAnalyzer for context-aware recommendations.
|
|
9
|
+
*
|
|
10
|
+
* @see Design: .kiro/specs/054b-figma-design-extract/design.md
|
|
11
|
+
* @requirements Req 1 (DesignExtractor Implementation)
|
|
12
|
+
* @spec 054b-figma-design-extract
|
|
13
|
+
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
48
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
49
|
+
};
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.DesignExtractor = void 0;
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const https_1 = __importDefault(require("https"));
|
|
55
|
+
const http_1 = __importDefault(require("http"));
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// DesignExtractor
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
/**
|
|
60
|
+
* Orchestrates extraction from Figma via dual-MCP strategy and generates
|
|
61
|
+
* design-outline.md documents.
|
|
62
|
+
*
|
|
63
|
+
* Uses:
|
|
64
|
+
* - Kiro Figma Power for rich design context (component structure, layout)
|
|
65
|
+
* - figma-console-mcp via ConsoleMCPClient for variables and styles
|
|
66
|
+
* - TokenTranslator for Figma value → DesignerPunk token matching
|
|
67
|
+
* - VariantAnalyzer for context-aware variant mapping recommendations
|
|
68
|
+
*/
|
|
69
|
+
class DesignExtractor {
|
|
70
|
+
constructor(consoleMcp, translator, analyzer, kiroPower, mcpDocs) {
|
|
71
|
+
this.consoleMcp = consoleMcp;
|
|
72
|
+
this.translator = translator;
|
|
73
|
+
this.analyzer = analyzer;
|
|
74
|
+
this.kiroPower = kiroPower;
|
|
75
|
+
this.mcpDocs = mcpDocs;
|
|
76
|
+
}
|
|
77
|
+
// -------------------------------------------------------------------------
|
|
78
|
+
// readFigmaComponent (Task 3.2)
|
|
79
|
+
// -------------------------------------------------------------------------
|
|
80
|
+
/**
|
|
81
|
+
* Read a Figma component via dual-MCP strategy.
|
|
82
|
+
*
|
|
83
|
+
* Primary: Kiro Figma Power `get_design_context` for rich component
|
|
84
|
+
* structure (layout, properties, visual states).
|
|
85
|
+
* Fallback: `get_metadata` + figma-console-mcp `figma_get_component`
|
|
86
|
+
* if `get_design_context` lacks detail or Kiro Power is unavailable.
|
|
87
|
+
*
|
|
88
|
+
* @param fileKey - The Figma file key.
|
|
89
|
+
* @param nodeId - The node ID of the component to extract.
|
|
90
|
+
* @returns An ExtractedComponent with structure, layout, and states.
|
|
91
|
+
* @throws Error if component cannot be read from either MCP source.
|
|
92
|
+
*/
|
|
93
|
+
async readFigmaComponent(fileKey, nodeId) {
|
|
94
|
+
// Try primary path: Kiro Figma Power
|
|
95
|
+
if (this.kiroPower) {
|
|
96
|
+
try {
|
|
97
|
+
const designContext = await this.kiroPower.getDesignContext(fileKey, nodeId);
|
|
98
|
+
if (designContext.code && designContext.code.trim().length > 0) {
|
|
99
|
+
const extracted = this.parseDesignContext(designContext);
|
|
100
|
+
if (extracted.name) {
|
|
101
|
+
return {
|
|
102
|
+
...extracted,
|
|
103
|
+
rawDesignContext: designContext.code,
|
|
104
|
+
source: 'kiro-power',
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Kiro Power failed — fall through to fallback
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Fallback: get_metadata + figma_get_component
|
|
114
|
+
return this.readFigmaComponentFallback(fileKey, nodeId);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Parse Kiro Figma Power `get_design_context` response into an
|
|
118
|
+
* ExtractedComponent.
|
|
119
|
+
*
|
|
120
|
+
* Extracts component name, description, variants, states, properties,
|
|
121
|
+
* and layout from the generated code string.
|
|
122
|
+
*/
|
|
123
|
+
parseDesignContext(response) {
|
|
124
|
+
const code = response.code ?? '';
|
|
125
|
+
return {
|
|
126
|
+
name: this.extractComponentName(code),
|
|
127
|
+
description: this.extractDescription(code),
|
|
128
|
+
variants: this.extractVariants(code),
|
|
129
|
+
states: this.extractStates(code),
|
|
130
|
+
properties: this.extractProperties(code),
|
|
131
|
+
layout: this.extractLayout(code),
|
|
132
|
+
source: 'kiro-power',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Fallback component reading via get_metadata + figma_get_component.
|
|
137
|
+
*
|
|
138
|
+
* Primary extraction path when Kiro Power is unavailable (which is the
|
|
139
|
+
* common case). Extracts structured layout data, boundVariables, fills,
|
|
140
|
+
* and cornerRadius directly from the Console MCP component response.
|
|
141
|
+
*/
|
|
142
|
+
async readFigmaComponentFallback(fileKey, nodeId) {
|
|
143
|
+
// Try metadata from Kiro Power if available
|
|
144
|
+
let rawMetadata;
|
|
145
|
+
if (this.kiroPower) {
|
|
146
|
+
try {
|
|
147
|
+
const metadata = await this.kiroPower.getMetadata(fileKey, nodeId);
|
|
148
|
+
rawMetadata = metadata.xml;
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// Metadata unavailable — continue without it
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Get component data from figma-console-mcp
|
|
155
|
+
let componentData;
|
|
156
|
+
try {
|
|
157
|
+
componentData = await this.consoleMcp.getComponent(fileKey, nodeId);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
161
|
+
throw new Error(`Failed to read Figma component (file: ${fileKey}, node: ${nodeId}): ${msg}`);
|
|
162
|
+
}
|
|
163
|
+
if (!componentData.name) {
|
|
164
|
+
throw new Error(`Component not found or invalid node ID (file: ${fileKey}, node: ${nodeId})`);
|
|
165
|
+
}
|
|
166
|
+
// Build variants from variantProperties map
|
|
167
|
+
const variants = [];
|
|
168
|
+
if (componentData.variantProperties) {
|
|
169
|
+
const propEntries = Object.entries(componentData.variantProperties);
|
|
170
|
+
if (propEntries.length > 0) {
|
|
171
|
+
// Generate variant combinations from the first property's values
|
|
172
|
+
const [firstProp, firstValues] = propEntries[0];
|
|
173
|
+
for (const val of firstValues) {
|
|
174
|
+
variants.push({
|
|
175
|
+
name: `${firstProp}=${val}`,
|
|
176
|
+
properties: { [firstProp]: val },
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Extract component properties and states from children's componentProperties.
|
|
182
|
+
// Children of a COMPONENT_SET carry componentProperties like:
|
|
183
|
+
// { "State": { value: "Incomplete", type: "VARIANT" },
|
|
184
|
+
// "Size": { value: "Sm", type: "VARIANT" },
|
|
185
|
+
// "Show Label#1231:0": { type: "BOOLEAN", value: false } }
|
|
186
|
+
const { properties, states: childStates } = this.extractChildComponentProperties(componentData);
|
|
187
|
+
// Extract states from metadata XML if available, merge with child states
|
|
188
|
+
const metadataStates = rawMetadata ? this.extractStatesFromMetadata(rawMetadata) : [];
|
|
189
|
+
const stateNames = new Set(metadataStates.map(s => s.name));
|
|
190
|
+
for (const cs of childStates) {
|
|
191
|
+
if (!stateNames.has(cs.name)) {
|
|
192
|
+
metadataStates.push(cs);
|
|
193
|
+
stateNames.add(cs.name);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Extract structured layout data from component children
|
|
197
|
+
const { layout, boundVariableMap, cornerRadius, fills } = this.extractLayoutFromComponentData(componentData);
|
|
198
|
+
return {
|
|
199
|
+
name: componentData.name,
|
|
200
|
+
description: componentData.description ?? '',
|
|
201
|
+
variants,
|
|
202
|
+
states: metadataStates,
|
|
203
|
+
properties,
|
|
204
|
+
layout,
|
|
205
|
+
boundVariableMap,
|
|
206
|
+
cornerRadius,
|
|
207
|
+
fills,
|
|
208
|
+
rawMetadata,
|
|
209
|
+
source: 'console-mcp-fallback',
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Extract structured layout data from a Console MCP component response.
|
|
214
|
+
*
|
|
215
|
+
* Walks the component's children (variant instances in a component set)
|
|
216
|
+
* to extract padding, itemSpacing, cornerRadius, fills, and boundVariables.
|
|
217
|
+
* Uses the first child with layout data as the representative, since
|
|
218
|
+
* variant children typically share the same structural tokens.
|
|
219
|
+
*
|
|
220
|
+
* boundVariables entries use VARIABLE_ALIAS format:
|
|
221
|
+
* { "paddingLeft": { "type": "VARIABLE_ALIAS", "id": "VariableID:..." } }
|
|
222
|
+
*
|
|
223
|
+
* We resolve variable IDs to names via the bindings loaded separately
|
|
224
|
+
* in readTokenBindings(). Here we store the raw property→variableId map
|
|
225
|
+
* and also extract any inline variable name references.
|
|
226
|
+
*/
|
|
227
|
+
/**
|
|
228
|
+
* Extract structured layout data from a Console MCP component response.
|
|
229
|
+
*
|
|
230
|
+
* Walks the component's children recursively to extract padding,
|
|
231
|
+
* itemSpacing, cornerRadius, fills, and boundVariables. Uses the first
|
|
232
|
+
* child with layout data as the representative for spacing/layout, and
|
|
233
|
+
* collects boundVariables from all levels of the tree (since bindings
|
|
234
|
+
* often live on grandchildren — e.g. fill color bindings on inner frames).
|
|
235
|
+
*
|
|
236
|
+
* boundVariables entries use VARIABLE_ALIAS format:
|
|
237
|
+
* { "paddingLeft": { "type": "VARIABLE_ALIAS", "id": "VariableID:..." } }
|
|
238
|
+
*
|
|
239
|
+
* Fill-level boundVariables are nested inside the fills array:
|
|
240
|
+
* fills: [{ color: {...}, boundVariables: { color: { id: "..." } } }]
|
|
241
|
+
*
|
|
242
|
+
* We resolve variable IDs to names via the bindings loaded separately
|
|
243
|
+
* in readTokenBindings(). Here we store the raw property→variableId map.
|
|
244
|
+
*/
|
|
245
|
+
extractLayoutFromComponentData(componentData) {
|
|
246
|
+
const boundVariableMap = new Map();
|
|
247
|
+
let layout = { mode: 'none' };
|
|
248
|
+
let cornerRadius;
|
|
249
|
+
let fills;
|
|
250
|
+
// The component data may be a component set (with children) or a single component.
|
|
251
|
+
// Try children first, then fall back to the component itself.
|
|
252
|
+
const raw = componentData;
|
|
253
|
+
const children = raw.children;
|
|
254
|
+
const nodesToInspect = children && children.length > 0
|
|
255
|
+
? children
|
|
256
|
+
: [raw];
|
|
257
|
+
for (const node of nodesToInspect) {
|
|
258
|
+
// Extract layout mode from layoutMode field
|
|
259
|
+
const layoutMode = node.layoutMode;
|
|
260
|
+
if (layoutMode && layout.mode === 'none') {
|
|
261
|
+
if (layoutMode === 'HORIZONTAL')
|
|
262
|
+
layout.mode = 'horizontal';
|
|
263
|
+
else if (layoutMode === 'VERTICAL')
|
|
264
|
+
layout.mode = 'vertical';
|
|
265
|
+
}
|
|
266
|
+
// Extract spacing values — use first node that has them
|
|
267
|
+
const itemSpacing = node.itemSpacing;
|
|
268
|
+
if (itemSpacing != null && layout.itemSpacing == null) {
|
|
269
|
+
layout.itemSpacing = itemSpacing;
|
|
270
|
+
}
|
|
271
|
+
// Extract padding
|
|
272
|
+
const pTop = node.paddingTop;
|
|
273
|
+
const pRight = node.paddingRight;
|
|
274
|
+
const pBottom = node.paddingBottom;
|
|
275
|
+
const pLeft = node.paddingLeft;
|
|
276
|
+
if ((pTop != null || pRight != null || pBottom != null || pLeft != null) && !layout.padding) {
|
|
277
|
+
layout.padding = {
|
|
278
|
+
top: pTop,
|
|
279
|
+
right: pRight,
|
|
280
|
+
bottom: pBottom,
|
|
281
|
+
left: pLeft,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
// Extract corner radius
|
|
285
|
+
const cr = node.cornerRadius;
|
|
286
|
+
if (cr != null && cornerRadius == null) {
|
|
287
|
+
cornerRadius = cr;
|
|
288
|
+
}
|
|
289
|
+
// Extract fills from this node (top-level fills for the component)
|
|
290
|
+
const nodeFills = node.fills;
|
|
291
|
+
if (nodeFills && nodeFills.length > 0 && !fills) {
|
|
292
|
+
fills = nodeFills.map((f) => {
|
|
293
|
+
const color = f.color;
|
|
294
|
+
let colorStr;
|
|
295
|
+
if (color) {
|
|
296
|
+
const r = Math.round((color.r ?? 0) * 255);
|
|
297
|
+
const g = Math.round((color.g ?? 0) * 255);
|
|
298
|
+
const b = Math.round((color.b ?? 0) * 255);
|
|
299
|
+
colorStr = `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
300
|
+
}
|
|
301
|
+
// Extract fill-level boundVariables (e.g. color bound to a variable)
|
|
302
|
+
const fillBoundVars = f.boundVariables;
|
|
303
|
+
if (fillBoundVars) {
|
|
304
|
+
this.extractBoundVariables(fillBoundVars, boundVariableMap);
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
type: String(f.type ?? 'SOLID'),
|
|
308
|
+
color: colorStr,
|
|
309
|
+
opacity: f.opacity,
|
|
310
|
+
};
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
// Extract node-level boundVariables (spacing, padding, radius bindings)
|
|
314
|
+
const boundVars = node.boundVariables;
|
|
315
|
+
if (boundVars) {
|
|
316
|
+
this.extractBoundVariables(boundVars, boundVariableMap);
|
|
317
|
+
}
|
|
318
|
+
// Stop scanning siblings once we have layout data (spacing/padding)
|
|
319
|
+
if (layout.mode !== 'none')
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
// Always walk the full tree for boundVariables and deep fills.
|
|
323
|
+
// boundVariables and color bindings often live on grandchildren
|
|
324
|
+
// (e.g. fill color bindings on inner frames within instance children).
|
|
325
|
+
// We collect ALL of them, not just the first match.
|
|
326
|
+
for (const node of nodesToInspect) {
|
|
327
|
+
this.collectBoundVariablesRecursive(node, boundVariableMap, 0, 4);
|
|
328
|
+
}
|
|
329
|
+
// Collect fills from deep children that have boundVariables on their
|
|
330
|
+
// fills — these represent designer-intentional color assignments that
|
|
331
|
+
// the top-level fills may not capture.
|
|
332
|
+
const deepFills = this.collectDeepFills(nodesToInspect);
|
|
333
|
+
if (deepFills.length > 0) {
|
|
334
|
+
// Merge deep fills with top-level fills, deduplicating by color value
|
|
335
|
+
const existingColors = new Set((fills ?? []).map(f => f.color));
|
|
336
|
+
for (const df of deepFills) {
|
|
337
|
+
if (df.color && !existingColors.has(df.color)) {
|
|
338
|
+
if (!fills)
|
|
339
|
+
fills = [];
|
|
340
|
+
fills.push(df);
|
|
341
|
+
existingColors.add(df.color);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return { layout, boundVariableMap, cornerRadius, fills };
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Extract component properties and visual states from children's
|
|
349
|
+
* componentProperties fields.
|
|
350
|
+
*
|
|
351
|
+
* Walks all children (and grandchildren) looking for `componentProperties`
|
|
352
|
+
* objects. Extracts:
|
|
353
|
+
* - VARIANT properties with value matching known state names → StateDefinition
|
|
354
|
+
* - VARIANT properties → PropertyDefinition (with type from variant options)
|
|
355
|
+
* - BOOLEAN properties → PropertyDefinition
|
|
356
|
+
*
|
|
357
|
+
* Deduplicates by property name (strips Figma hash suffixes like "#1231:0").
|
|
358
|
+
*/
|
|
359
|
+
extractChildComponentProperties(componentData) {
|
|
360
|
+
const properties = [];
|
|
361
|
+
const states = [];
|
|
362
|
+
const seenProps = new Set();
|
|
363
|
+
const seenStates = new Set();
|
|
364
|
+
const stateKeywords = new Set([
|
|
365
|
+
'hover', 'focus', 'disabled', 'pressed', 'active', 'selected',
|
|
366
|
+
'error', 'loading', 'incomplete', 'complete', 'current',
|
|
367
|
+
]);
|
|
368
|
+
const raw = componentData;
|
|
369
|
+
const children = raw.children;
|
|
370
|
+
if (!children)
|
|
371
|
+
return { properties, states };
|
|
372
|
+
const walkNode = (node) => {
|
|
373
|
+
const cp = node.componentProperties;
|
|
374
|
+
if (cp) {
|
|
375
|
+
for (const [rawName, def] of Object.entries(cp)) {
|
|
376
|
+
// Strip Figma hash suffix (e.g. "Show Label#1231:0" → "Show Label")
|
|
377
|
+
const cleanName = rawName.replace(/#[\d:]+$/, '').trim();
|
|
378
|
+
if (seenProps.has(cleanName))
|
|
379
|
+
continue;
|
|
380
|
+
seenProps.add(cleanName);
|
|
381
|
+
if (def.type === 'VARIANT') {
|
|
382
|
+
const value = String(def.value ?? '');
|
|
383
|
+
// Check if this variant value is a visual state
|
|
384
|
+
if (stateKeywords.has(value.toLowerCase()) && !seenStates.has(value.toLowerCase())) {
|
|
385
|
+
states.push({ name: value.toLowerCase() });
|
|
386
|
+
seenStates.add(value.toLowerCase());
|
|
387
|
+
}
|
|
388
|
+
properties.push({
|
|
389
|
+
name: cleanName,
|
|
390
|
+
type: 'variant',
|
|
391
|
+
defaultValue: value,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
else if (def.type === 'BOOLEAN') {
|
|
395
|
+
properties.push({
|
|
396
|
+
name: cleanName,
|
|
397
|
+
type: 'boolean',
|
|
398
|
+
defaultValue: String(def.value ?? 'false'),
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// Recurse into children
|
|
404
|
+
const nodeChildren = node.children;
|
|
405
|
+
if (nodeChildren) {
|
|
406
|
+
for (const child of nodeChildren) {
|
|
407
|
+
walkNode(child);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
for (const child of children) {
|
|
412
|
+
walkNode(child);
|
|
413
|
+
}
|
|
414
|
+
return { properties, states };
|
|
415
|
+
}
|
|
416
|
+
// -------------------------------------------------------------------------
|
|
417
|
+
// Hierarchical Node Tree Construction (Task 1.3)
|
|
418
|
+
// -------------------------------------------------------------------------
|
|
419
|
+
/**
|
|
420
|
+
* Build a hierarchical node tree with per-node token classifications.
|
|
421
|
+
*
|
|
422
|
+
* Recursively walks the Figma node tree preserving parent-child
|
|
423
|
+
* relationships. Each node carries its own token classifications
|
|
424
|
+
* (semantic, primitive, unidentified) rather than flattening them.
|
|
425
|
+
*
|
|
426
|
+
* @param figmaNode - Raw Figma node object from API response
|
|
427
|
+
* @param depth - Current depth in the tree (root = 0)
|
|
428
|
+
* @param ancestors - Ancestor node types from root to parent
|
|
429
|
+
* @returns NodeWithClassifications tree
|
|
430
|
+
* @requirements Req 2 (Hierarchical Node Tree Preservation)
|
|
431
|
+
*/
|
|
432
|
+
buildNodeTree(figmaNode, depth = 0, ancestors = []) {
|
|
433
|
+
const nodeType = figmaNode.type ?? 'FRAME';
|
|
434
|
+
const validTypes = new Set([
|
|
435
|
+
'COMPONENT_SET', 'COMPONENT', 'INSTANCE', 'FRAME', 'TEXT',
|
|
436
|
+
]);
|
|
437
|
+
const type = validTypes.has(nodeType)
|
|
438
|
+
? nodeType
|
|
439
|
+
: 'FRAME';
|
|
440
|
+
const node = {
|
|
441
|
+
id: String(figmaNode.id ?? ''),
|
|
442
|
+
name: String(figmaNode.name ?? ''),
|
|
443
|
+
type,
|
|
444
|
+
depth,
|
|
445
|
+
ancestorChain: ancestors,
|
|
446
|
+
tokenClassifications: {
|
|
447
|
+
semanticIdentified: [],
|
|
448
|
+
primitiveIdentified: [],
|
|
449
|
+
unidentified: [],
|
|
450
|
+
},
|
|
451
|
+
children: [],
|
|
452
|
+
};
|
|
453
|
+
// Extract layout properties
|
|
454
|
+
node.layout = this.extractNodeLayout(figmaNode);
|
|
455
|
+
// Extract text style for TEXT nodes
|
|
456
|
+
if (type === 'TEXT') {
|
|
457
|
+
node.textStyle = this.extractTextStyle(figmaNode);
|
|
458
|
+
}
|
|
459
|
+
// Extract stroke colors
|
|
460
|
+
const strokes = figmaNode.strokes;
|
|
461
|
+
if (strokes?.length) {
|
|
462
|
+
const extracted = [];
|
|
463
|
+
for (const stroke of strokes) {
|
|
464
|
+
const c = stroke.color;
|
|
465
|
+
if (!c)
|
|
466
|
+
continue;
|
|
467
|
+
const r = Math.round((c.r ?? 0) * 255);
|
|
468
|
+
const g = Math.round((c.g ?? 0) * 255);
|
|
469
|
+
const b = Math.round((c.b ?? 0) * 255);
|
|
470
|
+
const a = (c.a ?? 1) * (stroke.opacity ?? 1);
|
|
471
|
+
extracted.push({ color: `rgba(${r}, ${g}, ${b}, ${a})` });
|
|
472
|
+
}
|
|
473
|
+
if (extracted.length)
|
|
474
|
+
node.strokes = extracted;
|
|
475
|
+
}
|
|
476
|
+
// Extract componentProperties for INSTANCE nodes
|
|
477
|
+
if (type === 'INSTANCE') {
|
|
478
|
+
node.componentProperties = this.extractNodeComponentProperties(figmaNode);
|
|
479
|
+
}
|
|
480
|
+
// Classify tokens for this node
|
|
481
|
+
this.classifyNodeTokens(figmaNode, node);
|
|
482
|
+
// Recursively build children
|
|
483
|
+
const children = figmaNode.children;
|
|
484
|
+
if (children) {
|
|
485
|
+
const newAncestors = [...ancestors, nodeType];
|
|
486
|
+
node.children = children.map(child => this.buildNodeTree(child, depth + 1, newAncestors));
|
|
487
|
+
}
|
|
488
|
+
return node;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Detect composition patterns in a node tree.
|
|
492
|
+
*
|
|
493
|
+
* Groups INSTANCE children by component name and identifies repeated
|
|
494
|
+
* usage patterns with shared properties and property variations.
|
|
495
|
+
* Applies recursively at every level of the node tree.
|
|
496
|
+
*
|
|
497
|
+
* @param nodeTree - Root of the classified node tree
|
|
498
|
+
* @returns Array of detected composition patterns across all tree levels
|
|
499
|
+
* @requirements Req 3 (Composition Pattern Detection)
|
|
500
|
+
*/
|
|
501
|
+
detectCompositionPatterns(nodeTree) {
|
|
502
|
+
const patterns = [];
|
|
503
|
+
this.detectPatternsAtLevel(nodeTree, patterns);
|
|
504
|
+
return patterns;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Detect composition patterns at a single level and recurse into children.
|
|
508
|
+
*/
|
|
509
|
+
detectPatternsAtLevel(node, patterns) {
|
|
510
|
+
if (node.children.length > 0) {
|
|
511
|
+
// Group INSTANCE children by component name
|
|
512
|
+
const grouped = new Map();
|
|
513
|
+
for (const child of node.children) {
|
|
514
|
+
if (child.type === 'INSTANCE') {
|
|
515
|
+
const existing = grouped.get(child.name);
|
|
516
|
+
if (existing) {
|
|
517
|
+
existing.push(child);
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
grouped.set(child.name, [child]);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
// Build patterns for groups with 2+ instances
|
|
525
|
+
for (const [componentName, instances] of grouped) {
|
|
526
|
+
if (instances.length < 2)
|
|
527
|
+
continue;
|
|
528
|
+
const shared = this.findSharedProperties(instances);
|
|
529
|
+
const variations = this.groupByPropertyVariations(instances, shared);
|
|
530
|
+
patterns.push({
|
|
531
|
+
componentName,
|
|
532
|
+
count: instances.length,
|
|
533
|
+
sharedProperties: shared,
|
|
534
|
+
propertyVariations: variations,
|
|
535
|
+
depth: instances[0].depth,
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
// Recurse into all children (not just INSTANCE)
|
|
539
|
+
for (const child of node.children) {
|
|
540
|
+
this.detectPatternsAtLevel(child, patterns);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Find properties shared across all instances in a group.
|
|
546
|
+
*
|
|
547
|
+
* A property is "shared" when every instance has the same value for it.
|
|
548
|
+
*/
|
|
549
|
+
findSharedProperties(instances) {
|
|
550
|
+
const first = instances[0].componentProperties;
|
|
551
|
+
if (!first || instances.length === 0)
|
|
552
|
+
return {};
|
|
553
|
+
const shared = {};
|
|
554
|
+
for (const [key, def] of Object.entries(first)) {
|
|
555
|
+
const allSame = instances.every(inst => {
|
|
556
|
+
const cp = inst.componentProperties;
|
|
557
|
+
if (!cp || !(key in cp))
|
|
558
|
+
return false;
|
|
559
|
+
return this.valuesEqual(cp[key].value, def.value);
|
|
560
|
+
});
|
|
561
|
+
if (allSame) {
|
|
562
|
+
shared[key] = def.value;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return shared;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Group instances by their non-shared property combinations.
|
|
569
|
+
*
|
|
570
|
+
* Returns distinct property value combinations with counts.
|
|
571
|
+
*/
|
|
572
|
+
groupByPropertyVariations(instances, sharedProperties) {
|
|
573
|
+
const variationMap = new Map();
|
|
574
|
+
for (const inst of instances) {
|
|
575
|
+
const cp = inst.componentProperties;
|
|
576
|
+
const varying = {};
|
|
577
|
+
if (cp) {
|
|
578
|
+
for (const [key, def] of Object.entries(cp)) {
|
|
579
|
+
if (!(key in sharedProperties)) {
|
|
580
|
+
varying[key] = def.value;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
const key = JSON.stringify(varying, Object.keys(varying).sort());
|
|
585
|
+
const existing = variationMap.get(key);
|
|
586
|
+
if (existing) {
|
|
587
|
+
existing.count++;
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
variationMap.set(key, { properties: varying, count: 1 });
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return Array.from(variationMap.values());
|
|
594
|
+
}
|
|
595
|
+
// -----------------------------------------------------------------------
|
|
596
|
+
// Screenshot Capture (Task 2.3)
|
|
597
|
+
// -----------------------------------------------------------------------
|
|
598
|
+
/**
|
|
599
|
+
* Capture a component screenshot via figma-console-mcp.
|
|
600
|
+
*
|
|
601
|
+
* Calls `figma_get_component_image` at 2x scale in PNG format.
|
|
602
|
+
* On failure, logs a warning and returns null so extraction can
|
|
603
|
+
* continue without a screenshot.
|
|
604
|
+
*
|
|
605
|
+
* @param fileKey - The Figma file key.
|
|
606
|
+
* @param nodeId - The node ID of the component to capture.
|
|
607
|
+
* @param outputDir - Directory for storing screenshot images.
|
|
608
|
+
* @param componentName - Component name for the filename.
|
|
609
|
+
* @param variant - Optional variant identifier for the filename.
|
|
610
|
+
* @returns ScreenshotMetadata or null if capture failed.
|
|
611
|
+
* @requirements Req 5 (Component Screenshots)
|
|
612
|
+
*/
|
|
613
|
+
async captureComponentScreenshot(fileUrl, nodeId, outputDir, componentName, variant) {
|
|
614
|
+
try {
|
|
615
|
+
const result = await this.consoleMcp.getComponentImage(fileUrl, nodeId, {
|
|
616
|
+
scale: 2,
|
|
617
|
+
format: 'png',
|
|
618
|
+
});
|
|
619
|
+
if (!result.imageUrl) {
|
|
620
|
+
console.warn(`[DesignExtractor] Screenshot capture returned no image URL for "${componentName}"`);
|
|
621
|
+
return null;
|
|
622
|
+
}
|
|
623
|
+
// Build filename
|
|
624
|
+
const safeName = componentName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
625
|
+
const safeVariant = variant
|
|
626
|
+
? '-' + variant.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '')
|
|
627
|
+
: '';
|
|
628
|
+
const filename = `${safeName}${safeVariant}.png`;
|
|
629
|
+
const relativePath = `./images/${filename}`;
|
|
630
|
+
// Download image to disk
|
|
631
|
+
const absPath = path.join(outputDir, 'images', filename);
|
|
632
|
+
try {
|
|
633
|
+
await this.downloadFile(result.imageUrl, absPath);
|
|
634
|
+
}
|
|
635
|
+
catch (dlErr) {
|
|
636
|
+
const msg = dlErr instanceof Error ? dlErr.message : String(dlErr);
|
|
637
|
+
console.warn(`[DesignExtractor] Image download failed for "${componentName}": ${msg}`);
|
|
638
|
+
}
|
|
639
|
+
return {
|
|
640
|
+
filePath: relativePath,
|
|
641
|
+
url: result.imageUrl,
|
|
642
|
+
format: 'png',
|
|
643
|
+
scale: 2,
|
|
644
|
+
variant,
|
|
645
|
+
capturedAt: new Date().toISOString(),
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
catch (error) {
|
|
649
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
650
|
+
console.warn(`[DesignExtractor] Screenshot capture failed for "${componentName}": ${msg}`);
|
|
651
|
+
return null;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
/** Download a file from a URL to a local path. */
|
|
655
|
+
downloadFile(url, dest) {
|
|
656
|
+
return new Promise((resolve, reject) => {
|
|
657
|
+
const mod = url.startsWith('https') ? https_1.default : http_1.default;
|
|
658
|
+
const file = fs.createWriteStream(dest);
|
|
659
|
+
mod.get(url, (res) => {
|
|
660
|
+
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
661
|
+
file.close();
|
|
662
|
+
fs.unlinkSync(dest);
|
|
663
|
+
this.downloadFile(res.headers.location, dest).then(resolve, reject);
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
if (res.statusCode !== 200) {
|
|
667
|
+
file.close();
|
|
668
|
+
fs.unlinkSync(dest);
|
|
669
|
+
reject(new Error(`HTTP ${res.statusCode}`));
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
res.pipe(file);
|
|
673
|
+
file.on('finish', () => { file.close(); resolve(); });
|
|
674
|
+
}).on('error', (err) => {
|
|
675
|
+
file.close();
|
|
676
|
+
fs.unlinkSync(dest);
|
|
677
|
+
reject(err);
|
|
678
|
+
});
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Deep equality check for property values.
|
|
683
|
+
*/
|
|
684
|
+
valuesEqual(a, b) {
|
|
685
|
+
if (a === b)
|
|
686
|
+
return true;
|
|
687
|
+
if (a === null || b === null)
|
|
688
|
+
return false;
|
|
689
|
+
if (typeof a !== typeof b)
|
|
690
|
+
return false;
|
|
691
|
+
if (typeof a === 'object') {
|
|
692
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
693
|
+
}
|
|
694
|
+
return false;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Extract layout properties from a single Figma node.
|
|
698
|
+
*
|
|
699
|
+
* Returns undefined when the node has no layout-related properties,
|
|
700
|
+
* keeping the node tree compact.
|
|
701
|
+
*/
|
|
702
|
+
extractNodeLayout(node) {
|
|
703
|
+
const layoutMode = node.layoutMode;
|
|
704
|
+
const pTop = node.paddingTop;
|
|
705
|
+
const pRight = node.paddingRight;
|
|
706
|
+
const pBottom = node.paddingBottom;
|
|
707
|
+
const pLeft = node.paddingLeft;
|
|
708
|
+
const itemSpacing = node.itemSpacing;
|
|
709
|
+
const counterAxisSpacing = node.counterAxisSpacing;
|
|
710
|
+
const cornerRadius = node.cornerRadius;
|
|
711
|
+
const width = node.width;
|
|
712
|
+
const height = node.height;
|
|
713
|
+
const layoutSizingH = node.layoutSizingHorizontal;
|
|
714
|
+
const layoutSizingV = node.layoutSizingVertical;
|
|
715
|
+
const primaryAlign = node.primaryAxisAlignItems;
|
|
716
|
+
const counterAlign = node.counterAxisAlignItems;
|
|
717
|
+
const layoutAlign = node.layoutAlign;
|
|
718
|
+
const layoutGrow = node.layoutGrow;
|
|
719
|
+
const opacity = node.opacity;
|
|
720
|
+
const strokeWeight = node.strokeWeight;
|
|
721
|
+
const strokeAlign = node.strokeAlign;
|
|
722
|
+
const hasLayout = layoutMode != null ||
|
|
723
|
+
pTop != null || pRight != null || pBottom != null || pLeft != null ||
|
|
724
|
+
itemSpacing != null || counterAxisSpacing != null || cornerRadius != null ||
|
|
725
|
+
width != null || height != null || opacity != null || strokeWeight != null;
|
|
726
|
+
if (!hasLayout)
|
|
727
|
+
return undefined;
|
|
728
|
+
const layout = {};
|
|
729
|
+
if (layoutMode === 'HORIZONTAL' || layoutMode === 'VERTICAL') {
|
|
730
|
+
layout.layoutMode = layoutMode;
|
|
731
|
+
}
|
|
732
|
+
else if (layoutMode) {
|
|
733
|
+
layout.layoutMode = 'NONE';
|
|
734
|
+
}
|
|
735
|
+
if (pTop != null || pRight != null || pBottom != null || pLeft != null) {
|
|
736
|
+
layout.padding = {
|
|
737
|
+
top: pTop ?? 0,
|
|
738
|
+
right: pRight ?? 0,
|
|
739
|
+
bottom: pBottom ?? 0,
|
|
740
|
+
left: pLeft ?? 0,
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
if (itemSpacing != null)
|
|
744
|
+
layout.itemSpacing = itemSpacing;
|
|
745
|
+
if (counterAxisSpacing != null)
|
|
746
|
+
layout.counterAxisSpacing = counterAxisSpacing;
|
|
747
|
+
if (cornerRadius != null)
|
|
748
|
+
layout.cornerRadius = cornerRadius;
|
|
749
|
+
if (width != null)
|
|
750
|
+
layout.width = width;
|
|
751
|
+
if (height != null)
|
|
752
|
+
layout.height = height;
|
|
753
|
+
if (layoutSizingH === 'FIXED' || layoutSizingH === 'HUG' || layoutSizingH === 'FILL') {
|
|
754
|
+
layout.layoutSizingHorizontal = layoutSizingH;
|
|
755
|
+
}
|
|
756
|
+
if (layoutSizingV === 'FIXED' || layoutSizingV === 'HUG' || layoutSizingV === 'FILL') {
|
|
757
|
+
layout.layoutSizingVertical = layoutSizingV;
|
|
758
|
+
}
|
|
759
|
+
if (primaryAlign)
|
|
760
|
+
layout.primaryAxisAlignItems = primaryAlign;
|
|
761
|
+
if (counterAlign)
|
|
762
|
+
layout.counterAxisAlignItems = counterAlign;
|
|
763
|
+
if (layoutAlign)
|
|
764
|
+
layout.layoutAlign = layoutAlign;
|
|
765
|
+
if (layoutGrow != null)
|
|
766
|
+
layout.layoutGrow = layoutGrow;
|
|
767
|
+
if (opacity != null && opacity !== 1)
|
|
768
|
+
layout.opacity = opacity;
|
|
769
|
+
if (strokeWeight != null && strokeWeight > 0)
|
|
770
|
+
layout.strokeWeight = strokeWeight;
|
|
771
|
+
if (strokeAlign)
|
|
772
|
+
layout.strokeAlign = strokeAlign;
|
|
773
|
+
return layout;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Extract text style properties from a TEXT node.
|
|
777
|
+
*/
|
|
778
|
+
extractTextStyle(node) {
|
|
779
|
+
const style = {};
|
|
780
|
+
let hasData = false;
|
|
781
|
+
const chars = node.characters;
|
|
782
|
+
if (chars != null) {
|
|
783
|
+
style.characters = chars;
|
|
784
|
+
hasData = true;
|
|
785
|
+
}
|
|
786
|
+
const fontSize = node.fontSize;
|
|
787
|
+
if (fontSize != null) {
|
|
788
|
+
style.fontSize = fontSize;
|
|
789
|
+
hasData = true;
|
|
790
|
+
}
|
|
791
|
+
const fontName = node.fontName;
|
|
792
|
+
if (fontName?.family) {
|
|
793
|
+
style.fontFamily = fontName.family;
|
|
794
|
+
hasData = true;
|
|
795
|
+
}
|
|
796
|
+
if (fontName?.style) {
|
|
797
|
+
style.fontStyle = fontName.style;
|
|
798
|
+
hasData = true;
|
|
799
|
+
}
|
|
800
|
+
const fontWeight = node.fontWeight;
|
|
801
|
+
if (fontWeight != null) {
|
|
802
|
+
style.fontWeight = fontWeight;
|
|
803
|
+
hasData = true;
|
|
804
|
+
}
|
|
805
|
+
const lh = node.lineHeight;
|
|
806
|
+
if (lh?.value != null && lh.unit !== 'AUTO') {
|
|
807
|
+
style.lineHeight = lh.value;
|
|
808
|
+
hasData = true;
|
|
809
|
+
}
|
|
810
|
+
const ls = node.letterSpacing;
|
|
811
|
+
if (ls?.value != null && ls.value !== 0) {
|
|
812
|
+
style.letterSpacing = ls.value;
|
|
813
|
+
hasData = true;
|
|
814
|
+
}
|
|
815
|
+
const tah = node.textAlignHorizontal;
|
|
816
|
+
if (tah) {
|
|
817
|
+
style.textAlignHorizontal = tah;
|
|
818
|
+
hasData = true;
|
|
819
|
+
}
|
|
820
|
+
const tav = node.textAlignVertical;
|
|
821
|
+
if (tav) {
|
|
822
|
+
style.textAlignVertical = tav;
|
|
823
|
+
hasData = true;
|
|
824
|
+
}
|
|
825
|
+
return hasData ? style : undefined;
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Extract componentProperties from an INSTANCE node.
|
|
829
|
+
*
|
|
830
|
+
* Strips Figma hash suffixes (e.g. "Show Label#1231:0" → "Show Label")
|
|
831
|
+
* and returns undefined when no properties exist.
|
|
832
|
+
*/
|
|
833
|
+
extractNodeComponentProperties(node) {
|
|
834
|
+
const cp = node.componentProperties;
|
|
835
|
+
if (!cp || Object.keys(cp).length === 0)
|
|
836
|
+
return undefined;
|
|
837
|
+
const result = {};
|
|
838
|
+
for (const [rawName, def] of Object.entries(cp)) {
|
|
839
|
+
const cleanName = rawName.replace(/#[\d:]+$/, '').trim();
|
|
840
|
+
const type = def.type;
|
|
841
|
+
result[cleanName] = { type, value: def.value };
|
|
842
|
+
}
|
|
843
|
+
return result;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Classify tokens for a single Figma node using TokenTranslator.
|
|
847
|
+
*
|
|
848
|
+
* Collects spacing, radius, and fill-color properties from the node,
|
|
849
|
+
* translates each via the translator, and sorts results into the
|
|
850
|
+
* three-tier classification buckets on the node.
|
|
851
|
+
*/
|
|
852
|
+
classifyNodeTokens(figmaNode, node) {
|
|
853
|
+
const propertiesToClassify = [];
|
|
854
|
+
// Spacing properties
|
|
855
|
+
const spacingProps = [
|
|
856
|
+
['paddingTop', 'padding-top'],
|
|
857
|
+
['paddingRight', 'padding-right'],
|
|
858
|
+
['paddingBottom', 'padding-bottom'],
|
|
859
|
+
['paddingLeft', 'padding-left'],
|
|
860
|
+
['itemSpacing', 'item-spacing'],
|
|
861
|
+
['counterAxisSpacing', 'counter-axis-spacing'],
|
|
862
|
+
];
|
|
863
|
+
const boundVars = figmaNode.boundVariables;
|
|
864
|
+
const layoutMode = figmaNode.layoutMode;
|
|
865
|
+
const nodeType = figmaNode.type;
|
|
866
|
+
const isLeaf = nodeType === 'TEXT' || nodeType === 'VECTOR'
|
|
867
|
+
|| nodeType === 'ELLIPSE' || nodeType === 'LINE'
|
|
868
|
+
|| nodeType === 'STAR' || nodeType === 'POLYGON';
|
|
869
|
+
for (const [figmaProp, cssProp] of spacingProps) {
|
|
870
|
+
const value = figmaNode[figmaProp];
|
|
871
|
+
if (value == null)
|
|
872
|
+
continue;
|
|
873
|
+
// Skip irrelevant zero-value defaults
|
|
874
|
+
if (cssProp === 'counter-axis-spacing' && value === 0)
|
|
875
|
+
continue;
|
|
876
|
+
if (cssProp === 'item-spacing' && layoutMode === 'NONE')
|
|
877
|
+
continue;
|
|
878
|
+
if (isLeaf && cssProp.startsWith('padding-') && value === 0)
|
|
879
|
+
continue;
|
|
880
|
+
const varName = this.getBoundVariableName(boundVars, figmaProp);
|
|
881
|
+
propertiesToClassify.push({
|
|
882
|
+
property: cssProp,
|
|
883
|
+
figmaVarName: varName,
|
|
884
|
+
rawValue: value,
|
|
885
|
+
category: 'spacing',
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
// Corner radius
|
|
889
|
+
const cornerRadius = figmaNode.cornerRadius;
|
|
890
|
+
if (cornerRadius != null && cornerRadius !== 0) {
|
|
891
|
+
const varName = this.getBoundVariableName(boundVars, 'cornerRadius');
|
|
892
|
+
propertiesToClassify.push({
|
|
893
|
+
property: 'border-radius',
|
|
894
|
+
figmaVarName: varName,
|
|
895
|
+
rawValue: cornerRadius,
|
|
896
|
+
category: 'radius',
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
// Fill colors
|
|
900
|
+
const fills = figmaNode.fills;
|
|
901
|
+
if (fills) {
|
|
902
|
+
for (const fill of fills) {
|
|
903
|
+
const color = fill.color;
|
|
904
|
+
if (!color)
|
|
905
|
+
continue;
|
|
906
|
+
const r = Math.round((color.r ?? 0) * 255);
|
|
907
|
+
const g = Math.round((color.g ?? 0) * 255);
|
|
908
|
+
const b = Math.round((color.b ?? 0) * 255);
|
|
909
|
+
const a = (color.a ?? 1) * (fill.opacity ?? 1);
|
|
910
|
+
const rgba = `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
911
|
+
const fillBv = fill.boundVariables;
|
|
912
|
+
const varName = this.getBoundVariableName(fillBv, 'color');
|
|
913
|
+
propertiesToClassify.push({
|
|
914
|
+
property: 'fill',
|
|
915
|
+
figmaVarName: varName,
|
|
916
|
+
rawValue: rgba,
|
|
917
|
+
category: 'color',
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
// Opacity
|
|
922
|
+
const opacity = figmaNode.opacity;
|
|
923
|
+
if (opacity != null && opacity !== 1) {
|
|
924
|
+
const varName = this.getBoundVariableName(boundVars, 'opacity');
|
|
925
|
+
propertiesToClassify.push({
|
|
926
|
+
property: 'opacity',
|
|
927
|
+
figmaVarName: varName,
|
|
928
|
+
rawValue: opacity,
|
|
929
|
+
category: 'opacity',
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
// Stroke weight
|
|
933
|
+
const strokeWeight = figmaNode.strokeWeight;
|
|
934
|
+
if (strokeWeight != null && strokeWeight > 0) {
|
|
935
|
+
const varName = this.getBoundVariableName(boundVars, 'strokeWeight');
|
|
936
|
+
propertiesToClassify.push({
|
|
937
|
+
property: 'border-width',
|
|
938
|
+
figmaVarName: varName,
|
|
939
|
+
rawValue: strokeWeight,
|
|
940
|
+
category: 'borderWidth',
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
// Stroke colors
|
|
944
|
+
const strokes = figmaNode.strokes;
|
|
945
|
+
if (strokes) {
|
|
946
|
+
for (const stroke of strokes) {
|
|
947
|
+
const c = stroke.color;
|
|
948
|
+
if (!c)
|
|
949
|
+
continue;
|
|
950
|
+
const r = Math.round((c.r ?? 0) * 255);
|
|
951
|
+
const g = Math.round((c.g ?? 0) * 255);
|
|
952
|
+
const b = Math.round((c.b ?? 0) * 255);
|
|
953
|
+
const a = (c.a ?? 1) * (stroke.opacity ?? 1);
|
|
954
|
+
const strokeBv = stroke.boundVariables;
|
|
955
|
+
const varName = this.getBoundVariableName(strokeBv, 'color');
|
|
956
|
+
propertiesToClassify.push({
|
|
957
|
+
property: 'stroke',
|
|
958
|
+
figmaVarName: varName,
|
|
959
|
+
rawValue: `rgba(${r}, ${g}, ${b}, ${a})`,
|
|
960
|
+
category: 'color',
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
// Typography properties (TEXT nodes only)
|
|
965
|
+
if (nodeType === 'TEXT') {
|
|
966
|
+
const fontSize = figmaNode.fontSize;
|
|
967
|
+
if (fontSize != null) {
|
|
968
|
+
const varName = this.getBoundVariableName(boundVars, 'fontSize');
|
|
969
|
+
propertiesToClassify.push({
|
|
970
|
+
property: 'font-size',
|
|
971
|
+
figmaVarName: varName,
|
|
972
|
+
rawValue: fontSize,
|
|
973
|
+
category: 'fontSize',
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
const fontWeight = figmaNode.fontWeight;
|
|
977
|
+
if (fontWeight != null) {
|
|
978
|
+
const varName = this.getBoundVariableName(boundVars, 'fontWeight');
|
|
979
|
+
propertiesToClassify.push({
|
|
980
|
+
property: 'font-weight',
|
|
981
|
+
figmaVarName: varName,
|
|
982
|
+
rawValue: fontWeight,
|
|
983
|
+
category: 'fontWeight',
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
const lh = figmaNode.lineHeight;
|
|
987
|
+
if (lh?.value != null && lh.unit !== 'AUTO') {
|
|
988
|
+
const varName = this.getBoundVariableName(boundVars, 'lineHeight');
|
|
989
|
+
propertiesToClassify.push({
|
|
990
|
+
property: 'line-height',
|
|
991
|
+
figmaVarName: varName,
|
|
992
|
+
rawValue: lh.value,
|
|
993
|
+
category: 'lineHeight',
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
const ls = figmaNode.letterSpacing;
|
|
997
|
+
if (ls?.value != null && ls.value !== 0) {
|
|
998
|
+
const varName = this.getBoundVariableName(boundVars, 'letterSpacing');
|
|
999
|
+
propertiesToClassify.push({
|
|
1000
|
+
property: 'letter-spacing',
|
|
1001
|
+
figmaVarName: varName,
|
|
1002
|
+
rawValue: ls.value,
|
|
1003
|
+
category: 'letterSpacing',
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
// Classify each property
|
|
1008
|
+
for (const { property, figmaVarName, rawValue, category } of propertiesToClassify) {
|
|
1009
|
+
const result = this.translator.translate(figmaVarName, rawValue, category);
|
|
1010
|
+
const tier = this.translator.classifyTokenMatch(result);
|
|
1011
|
+
// Value-based matches → Unidentified with suggestion (only bindings earn Identified)
|
|
1012
|
+
if (result.matchMethod === 'value' && tier !== 'unidentified') {
|
|
1013
|
+
node.tokenClassifications.unidentified.push({
|
|
1014
|
+
property,
|
|
1015
|
+
rawValue: result.rawValue,
|
|
1016
|
+
reason: figmaVarName ? 'unresolved-binding' : 'value-match',
|
|
1017
|
+
suggestedToken: result.semantic ?? result.primitive ?? result.token,
|
|
1018
|
+
boundVariableId: figmaVarName,
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
else if (tier === 'semantic') {
|
|
1022
|
+
node.tokenClassifications.semanticIdentified.push(this.translator.toClassifiedToken(result, property));
|
|
1023
|
+
}
|
|
1024
|
+
else if (tier === 'primitive') {
|
|
1025
|
+
node.tokenClassifications.primitiveIdentified.push(this.translator.toClassifiedToken(result, property));
|
|
1026
|
+
}
|
|
1027
|
+
else {
|
|
1028
|
+
node.tokenClassifications.unidentified.push(this.translator.toUnidentifiedValue(result, property));
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Extract a Figma variable name from a node's boundVariables for a
|
|
1034
|
+
* given property.
|
|
1035
|
+
*
|
|
1036
|
+
* Handles both single-binding objects and array-of-bindings.
|
|
1037
|
+
*/
|
|
1038
|
+
getBoundVariableName(boundVars, property) {
|
|
1039
|
+
if (!boundVars)
|
|
1040
|
+
return undefined;
|
|
1041
|
+
const binding = boundVars[property];
|
|
1042
|
+
if (!binding || typeof binding !== 'object')
|
|
1043
|
+
return undefined;
|
|
1044
|
+
const bindingObj = binding;
|
|
1045
|
+
const entry = Array.isArray(bindingObj) ? bindingObj[0] : bindingObj;
|
|
1046
|
+
if (!entry || typeof entry !== 'object')
|
|
1047
|
+
return undefined;
|
|
1048
|
+
const entryObj = entry;
|
|
1049
|
+
return entryObj.id;
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Extract boundVariables from a node's boundVariables object into the map.
|
|
1053
|
+
*/
|
|
1054
|
+
extractBoundVariables(boundVars, boundVariableMap) {
|
|
1055
|
+
for (const [prop, binding] of Object.entries(boundVars)) {
|
|
1056
|
+
if (!binding || typeof binding !== 'object')
|
|
1057
|
+
continue;
|
|
1058
|
+
const bindingObj = binding;
|
|
1059
|
+
const bindingEntries = Array.isArray(bindingObj) ? bindingObj : [bindingObj];
|
|
1060
|
+
for (const entry of bindingEntries) {
|
|
1061
|
+
const entryObj = entry;
|
|
1062
|
+
const varId = entryObj.id;
|
|
1063
|
+
if (varId && !boundVariableMap.has(prop)) {
|
|
1064
|
+
boundVariableMap.set(prop, varId);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Recursively walk a node tree to collect all boundVariables.
|
|
1071
|
+
*
|
|
1072
|
+
* Collects from node-level boundVariables and fill-level boundVariables
|
|
1073
|
+
* on all descendants up to maxDepth.
|
|
1074
|
+
*/
|
|
1075
|
+
collectBoundVariablesRecursive(node, boundVariableMap, depth, maxDepth) {
|
|
1076
|
+
if (depth > maxDepth)
|
|
1077
|
+
return;
|
|
1078
|
+
// Node-level boundVariables
|
|
1079
|
+
const boundVars = node.boundVariables;
|
|
1080
|
+
if (boundVars) {
|
|
1081
|
+
this.extractBoundVariables(boundVars, boundVariableMap);
|
|
1082
|
+
}
|
|
1083
|
+
// Fill-level boundVariables (color bindings inside fills array)
|
|
1084
|
+
const nodeFills = node.fills;
|
|
1085
|
+
if (nodeFills) {
|
|
1086
|
+
for (const fill of nodeFills) {
|
|
1087
|
+
const fillBoundVars = fill.boundVariables;
|
|
1088
|
+
if (fillBoundVars) {
|
|
1089
|
+
this.extractBoundVariables(fillBoundVars, boundVariableMap);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
// Recurse into children
|
|
1094
|
+
const children = node.children;
|
|
1095
|
+
if (children) {
|
|
1096
|
+
for (const child of children) {
|
|
1097
|
+
this.collectBoundVariablesRecursive(child, boundVariableMap, depth + 1, maxDepth);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
// -----------------------------------------------------------------------
|
|
1102
|
+
// Bound Variable Batch Resolution (Task 1.5)
|
|
1103
|
+
// -----------------------------------------------------------------------
|
|
1104
|
+
/**
|
|
1105
|
+
* Walk a raw Figma node tree and collect all bound variable entries
|
|
1106
|
+
* with full node context.
|
|
1107
|
+
*
|
|
1108
|
+
* Checks spacing properties, cornerRadius, and fill colors for
|
|
1109
|
+
* boundVariables. Returns all entries (not deduplicated) — dedup
|
|
1110
|
+
* happens in batchResolveBoundVariables.
|
|
1111
|
+
*
|
|
1112
|
+
* @param figmaNode - Raw Figma node object from API response
|
|
1113
|
+
* @param depth - Current depth in the tree (root = 0)
|
|
1114
|
+
* @param ancestors - Ancestor node types from root to parent
|
|
1115
|
+
* @returns Array of BoundVariableEntry with full node context
|
|
1116
|
+
* @requirements Req 4 (Bound Variable Batch Resolution)
|
|
1117
|
+
*/
|
|
1118
|
+
collectBoundVariableIds(figmaNode, depth = 0, ancestors = []) {
|
|
1119
|
+
const entries = [];
|
|
1120
|
+
const nodeId = String(figmaNode.id ?? '');
|
|
1121
|
+
const nodeName = String(figmaNode.name ?? '');
|
|
1122
|
+
const nodeType = String(figmaNode.type ?? 'FRAME');
|
|
1123
|
+
const boundVars = figmaNode.boundVariables;
|
|
1124
|
+
// Spacing properties
|
|
1125
|
+
const spacingProps = [
|
|
1126
|
+
['paddingTop', 'padding-top'],
|
|
1127
|
+
['paddingRight', 'padding-right'],
|
|
1128
|
+
['paddingBottom', 'padding-bottom'],
|
|
1129
|
+
['paddingLeft', 'padding-left'],
|
|
1130
|
+
['itemSpacing', 'item-spacing'],
|
|
1131
|
+
['counterAxisSpacing', 'counter-axis-spacing'],
|
|
1132
|
+
];
|
|
1133
|
+
for (const [figmaProp, cssProp] of spacingProps) {
|
|
1134
|
+
const value = figmaNode[figmaProp];
|
|
1135
|
+
if (value == null)
|
|
1136
|
+
continue;
|
|
1137
|
+
const varId = this.getBoundVariableName(boundVars, figmaProp);
|
|
1138
|
+
if (varId) {
|
|
1139
|
+
entries.push({
|
|
1140
|
+
variableId: varId,
|
|
1141
|
+
property: cssProp,
|
|
1142
|
+
nodeId,
|
|
1143
|
+
nodeName,
|
|
1144
|
+
ancestorChain: ancestors,
|
|
1145
|
+
rawValue: value,
|
|
1146
|
+
category: 'spacing',
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
// Corner radius
|
|
1151
|
+
const cornerRadius = figmaNode.cornerRadius;
|
|
1152
|
+
if (cornerRadius != null) {
|
|
1153
|
+
const varId = this.getBoundVariableName(boundVars, 'cornerRadius');
|
|
1154
|
+
if (varId) {
|
|
1155
|
+
entries.push({
|
|
1156
|
+
variableId: varId,
|
|
1157
|
+
property: 'border-radius',
|
|
1158
|
+
nodeId,
|
|
1159
|
+
nodeName,
|
|
1160
|
+
ancestorChain: ancestors,
|
|
1161
|
+
rawValue: cornerRadius,
|
|
1162
|
+
category: 'radius',
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
// Fill colors
|
|
1167
|
+
const fills = figmaNode.fills;
|
|
1168
|
+
if (fills) {
|
|
1169
|
+
for (const fill of fills) {
|
|
1170
|
+
const color = fill.color;
|
|
1171
|
+
if (!color)
|
|
1172
|
+
continue;
|
|
1173
|
+
const r = Math.round((color.r ?? 0) * 255);
|
|
1174
|
+
const g = Math.round((color.g ?? 0) * 255);
|
|
1175
|
+
const b = Math.round((color.b ?? 0) * 255);
|
|
1176
|
+
const a = (color.a ?? 1) * (fill.opacity ?? 1);
|
|
1177
|
+
const rgba = `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
1178
|
+
const fillBv = fill.boundVariables;
|
|
1179
|
+
const varId = this.getBoundVariableName(fillBv, 'color');
|
|
1180
|
+
if (varId) {
|
|
1181
|
+
entries.push({
|
|
1182
|
+
variableId: varId,
|
|
1183
|
+
property: 'fill',
|
|
1184
|
+
nodeId,
|
|
1185
|
+
nodeName,
|
|
1186
|
+
ancestorChain: ancestors,
|
|
1187
|
+
rawValue: rgba,
|
|
1188
|
+
category: 'color',
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
// Opacity
|
|
1194
|
+
const opacity = figmaNode.opacity;
|
|
1195
|
+
if (opacity != null && opacity !== 1) {
|
|
1196
|
+
const varId = this.getBoundVariableName(boundVars, 'opacity');
|
|
1197
|
+
if (varId) {
|
|
1198
|
+
entries.push({
|
|
1199
|
+
variableId: varId, property: 'opacity', nodeId, nodeName,
|
|
1200
|
+
ancestorChain: ancestors, rawValue: opacity, category: 'opacity',
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
// Stroke weight
|
|
1205
|
+
const strokeWeight = figmaNode.strokeWeight;
|
|
1206
|
+
if (strokeWeight != null && strokeWeight > 0) {
|
|
1207
|
+
const varId = this.getBoundVariableName(boundVars, 'strokeWeight');
|
|
1208
|
+
if (varId) {
|
|
1209
|
+
entries.push({
|
|
1210
|
+
variableId: varId, property: 'border-width', nodeId, nodeName,
|
|
1211
|
+
ancestorChain: ancestors, rawValue: strokeWeight, category: 'borderWidth',
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
// Stroke colors
|
|
1216
|
+
const strokes = figmaNode.strokes;
|
|
1217
|
+
if (strokes) {
|
|
1218
|
+
for (const stroke of strokes) {
|
|
1219
|
+
const sc = stroke.color;
|
|
1220
|
+
if (!sc)
|
|
1221
|
+
continue;
|
|
1222
|
+
const sr = Math.round((sc.r ?? 0) * 255);
|
|
1223
|
+
const sg = Math.round((sc.g ?? 0) * 255);
|
|
1224
|
+
const sb = Math.round((sc.b ?? 0) * 255);
|
|
1225
|
+
const sa = (sc.a ?? 1) * (stroke.opacity ?? 1);
|
|
1226
|
+
const strokeBv = stroke.boundVariables;
|
|
1227
|
+
const varId = this.getBoundVariableName(strokeBv, 'color');
|
|
1228
|
+
if (varId) {
|
|
1229
|
+
entries.push({
|
|
1230
|
+
variableId: varId, property: 'stroke', nodeId, nodeName,
|
|
1231
|
+
ancestorChain: ancestors, rawValue: `rgba(${sr}, ${sg}, ${sb}, ${sa})`, category: 'color',
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
// Typography bindings (TEXT nodes only)
|
|
1237
|
+
if (nodeType === 'TEXT') {
|
|
1238
|
+
const typoProps = [
|
|
1239
|
+
['fontSize', 'font-size', 'fontSize'],
|
|
1240
|
+
['fontWeight', 'font-weight', 'fontWeight'],
|
|
1241
|
+
['lineHeight', 'line-height', 'lineHeight'],
|
|
1242
|
+
['letterSpacing', 'letter-spacing', 'letterSpacing'],
|
|
1243
|
+
];
|
|
1244
|
+
for (const [figmaProp, cssProp, cat] of typoProps) {
|
|
1245
|
+
const varId = this.getBoundVariableName(boundVars, figmaProp);
|
|
1246
|
+
if (varId) {
|
|
1247
|
+
const raw = figmaNode[figmaProp];
|
|
1248
|
+
const rawVal = typeof raw === 'object' && raw !== null
|
|
1249
|
+
? raw.value ?? 0
|
|
1250
|
+
: raw ?? 0;
|
|
1251
|
+
entries.push({
|
|
1252
|
+
variableId: varId, property: cssProp, nodeId, nodeName,
|
|
1253
|
+
ancestorChain: ancestors, rawValue: rawVal, category: cat,
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
// Recurse into children
|
|
1259
|
+
const children = figmaNode.children;
|
|
1260
|
+
if (children) {
|
|
1261
|
+
const newAncestors = [...ancestors, nodeType];
|
|
1262
|
+
for (const child of children) {
|
|
1263
|
+
entries.push(...this.collectBoundVariableIds(child, depth + 1, newAncestors));
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
return entries;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Batch-resolve bound variable IDs via the Figma Plugin API.
|
|
1270
|
+
*
|
|
1271
|
+
* Deduplicates variable IDs, calls figma_execute to resolve names,
|
|
1272
|
+
* and returns a map of resolved names plus an array of unresolved
|
|
1273
|
+
* bindings with full node context.
|
|
1274
|
+
*
|
|
1275
|
+
* @param fileKey - The Figma file key
|
|
1276
|
+
* @param entries - BoundVariableEntry[] collected from the node tree
|
|
1277
|
+
* @returns Object with resolved map and unresolvedBindings array
|
|
1278
|
+
* @requirements Req 4 (Bound Variable Batch Resolution)
|
|
1279
|
+
*/
|
|
1280
|
+
async batchResolveBoundVariables(fileKey, entries) {
|
|
1281
|
+
const resolved = new Map();
|
|
1282
|
+
const unresolvedBindings = [];
|
|
1283
|
+
if (entries.length === 0) {
|
|
1284
|
+
return { resolved, unresolvedBindings };
|
|
1285
|
+
}
|
|
1286
|
+
// Deduplicate variable IDs
|
|
1287
|
+
const uniqueIds = [...new Set(entries.map(e => e.variableId))];
|
|
1288
|
+
// Build Plugin API code
|
|
1289
|
+
const code = `
|
|
1290
|
+
const results = {};
|
|
1291
|
+
const collections = {};
|
|
1292
|
+
for (const id of ${JSON.stringify(uniqueIds)}) {
|
|
1293
|
+
try {
|
|
1294
|
+
const v = await figma.variables.getVariableByIdAsync(id);
|
|
1295
|
+
if (v) {
|
|
1296
|
+
let collectionName = collections[v.variableCollectionId];
|
|
1297
|
+
if (!collectionName) {
|
|
1298
|
+
try {
|
|
1299
|
+
const c = await figma.variables.getVariableCollectionByIdAsync(v.variableCollectionId);
|
|
1300
|
+
collectionName = c ? c.name : '';
|
|
1301
|
+
} catch(e) { collectionName = ''; }
|
|
1302
|
+
collections[v.variableCollectionId] = collectionName;
|
|
1303
|
+
}
|
|
1304
|
+
results[id] = { name: v.name, collection: collectionName };
|
|
1305
|
+
}
|
|
1306
|
+
} catch (e) {
|
|
1307
|
+
// Variable not found — skip
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
return results;
|
|
1311
|
+
`.trim();
|
|
1312
|
+
try {
|
|
1313
|
+
const result = await this.consoleMcp.execute(fileKey, code);
|
|
1314
|
+
// Parse the result — may be wrapped in { result: { ... } } or { result: "..." }
|
|
1315
|
+
let resolvedData = {};
|
|
1316
|
+
if (result && typeof result === 'object') {
|
|
1317
|
+
const raw = result;
|
|
1318
|
+
let inner = raw.result ?? raw;
|
|
1319
|
+
if (typeof inner === 'string') {
|
|
1320
|
+
try {
|
|
1321
|
+
inner = JSON.parse(inner);
|
|
1322
|
+
}
|
|
1323
|
+
catch { /* not JSON */ }
|
|
1324
|
+
}
|
|
1325
|
+
if (inner && typeof inner === 'object') {
|
|
1326
|
+
resolvedData = inner;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
// Populate resolved map
|
|
1330
|
+
for (const [varId, info] of Object.entries(resolvedData)) {
|
|
1331
|
+
if (info?.name) {
|
|
1332
|
+
resolved.set(varId, info.name);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
// Build unresolvedBindings for IDs that failed
|
|
1336
|
+
for (const entry of entries) {
|
|
1337
|
+
if (!resolved.has(entry.variableId)) {
|
|
1338
|
+
unresolvedBindings.push({
|
|
1339
|
+
variableId: entry.variableId,
|
|
1340
|
+
property: entry.property,
|
|
1341
|
+
nodeId: entry.nodeId,
|
|
1342
|
+
nodeName: entry.nodeName,
|
|
1343
|
+
ancestorChain: entry.ancestorChain,
|
|
1344
|
+
reason: 'api-resolution-failed',
|
|
1345
|
+
});
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
catch {
|
|
1350
|
+
// API call failed entirely — all entries are unresolved
|
|
1351
|
+
for (const entry of entries) {
|
|
1352
|
+
unresolvedBindings.push({
|
|
1353
|
+
variableId: entry.variableId,
|
|
1354
|
+
property: entry.property,
|
|
1355
|
+
nodeId: entry.nodeId,
|
|
1356
|
+
nodeName: entry.nodeName,
|
|
1357
|
+
ancestorChain: entry.ancestorChain,
|
|
1358
|
+
reason: 'api-resolution-failed',
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
return { resolved, unresolvedBindings };
|
|
1363
|
+
}
|
|
1364
|
+
/**
|
|
1365
|
+
* Walk a NodeWithClassifications tree and reclassify unidentified values
|
|
1366
|
+
* that have a boundVariableId using resolved variable names.
|
|
1367
|
+
*
|
|
1368
|
+
* For each unidentified value with a boundVariableId found in the
|
|
1369
|
+
* resolvedMap, re-translates using the resolved name and moves
|
|
1370
|
+
* successfully classified tokens from unidentified to semantic or
|
|
1371
|
+
* primitive. Mutates the tree in place.
|
|
1372
|
+
*
|
|
1373
|
+
* @param nodeTree - Root of the classified node tree
|
|
1374
|
+
* @param resolvedMap - Map of variableId → resolved variable name
|
|
1375
|
+
* @requirements Req 4 (Bound Variable Batch Resolution)
|
|
1376
|
+
*/
|
|
1377
|
+
reclassifyWithResolvedBindings(nodeTree, resolvedMap) {
|
|
1378
|
+
const { unidentified } = nodeTree.tokenClassifications;
|
|
1379
|
+
const remaining = [];
|
|
1380
|
+
for (const entry of unidentified) {
|
|
1381
|
+
if (entry.boundVariableId && resolvedMap.has(entry.boundVariableId)) {
|
|
1382
|
+
const resolvedName = resolvedMap.get(entry.boundVariableId);
|
|
1383
|
+
// Use translateByBinding directly — no enrichResponse promotion.
|
|
1384
|
+
// The designer bound to THIS variable; honour the tier it lives at.
|
|
1385
|
+
const bindingResult = this.translator.translateByBinding(resolvedName);
|
|
1386
|
+
if (bindingResult.confidence === 'no-match') {
|
|
1387
|
+
// Binding resolved to a name but no matching token in DTCG —
|
|
1388
|
+
// likely a component-level variable that needs to be created.
|
|
1389
|
+
entry.reason = 'no-token-match';
|
|
1390
|
+
entry.suggestedToken = resolvedName;
|
|
1391
|
+
remaining.push(entry);
|
|
1392
|
+
continue;
|
|
1393
|
+
}
|
|
1394
|
+
// Determine tier from the token itself (alias = semantic, raw = primitive)
|
|
1395
|
+
const tokenObj = this.translator.lookupToken(bindingResult.token);
|
|
1396
|
+
const isAlias = tokenObj && typeof tokenObj.$value === 'string'
|
|
1397
|
+
&& tokenObj.$value.startsWith('{') && tokenObj.$value.endsWith('}');
|
|
1398
|
+
const classified = {
|
|
1399
|
+
property: entry.property,
|
|
1400
|
+
semanticToken: isAlias ? bindingResult.token : undefined,
|
|
1401
|
+
primitiveToken: isAlias
|
|
1402
|
+
? tokenObj.$value.slice(1, -1)
|
|
1403
|
+
: bindingResult.token,
|
|
1404
|
+
rawValue: bindingResult.rawValue,
|
|
1405
|
+
matchMethod: 'binding',
|
|
1406
|
+
confidence: 'exact',
|
|
1407
|
+
};
|
|
1408
|
+
if (isAlias) {
|
|
1409
|
+
nodeTree.tokenClassifications.semanticIdentified.push(classified);
|
|
1410
|
+
}
|
|
1411
|
+
else {
|
|
1412
|
+
nodeTree.tokenClassifications.primitiveIdentified.push(classified);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
else {
|
|
1416
|
+
remaining.push(entry);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
nodeTree.tokenClassifications.unidentified = remaining;
|
|
1420
|
+
// Recurse into children
|
|
1421
|
+
for (const child of nodeTree.children) {
|
|
1422
|
+
this.reclassifyWithResolvedBindings(child, resolvedMap);
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Collect fills from deep children that have boundVariables on their fills.
|
|
1427
|
+
*
|
|
1428
|
+
* These represent designer-intentional color assignments (variables bound
|
|
1429
|
+
* to fill colors) that may differ from the parent component's fills.
|
|
1430
|
+
* Returns deduplicated fills with their hex color values.
|
|
1431
|
+
*/
|
|
1432
|
+
collectDeepFills(nodes) {
|
|
1433
|
+
const result = [];
|
|
1434
|
+
const seenColors = new Set();
|
|
1435
|
+
const walk = (node, depth) => {
|
|
1436
|
+
if (depth > 4)
|
|
1437
|
+
return;
|
|
1438
|
+
const nodeFills = node.fills;
|
|
1439
|
+
if (nodeFills) {
|
|
1440
|
+
for (const fill of nodeFills) {
|
|
1441
|
+
// Only collect fills that have boundVariables (designer intent)
|
|
1442
|
+
const fillBv = fill.boundVariables;
|
|
1443
|
+
if (!fillBv || Object.keys(fillBv).length === 0)
|
|
1444
|
+
continue;
|
|
1445
|
+
const color = fill.color;
|
|
1446
|
+
if (!color)
|
|
1447
|
+
continue;
|
|
1448
|
+
const r = Math.round((color.r ?? 0) * 255);
|
|
1449
|
+
const g = Math.round((color.g ?? 0) * 255);
|
|
1450
|
+
const b = Math.round((color.b ?? 0) * 255);
|
|
1451
|
+
const hex = `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
1452
|
+
if (!seenColors.has(hex)) {
|
|
1453
|
+
seenColors.add(hex);
|
|
1454
|
+
result.push({
|
|
1455
|
+
type: String(fill.type ?? 'SOLID'),
|
|
1456
|
+
color: hex,
|
|
1457
|
+
opacity: fill.opacity,
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
const children = node.children;
|
|
1463
|
+
if (children) {
|
|
1464
|
+
for (const child of children) {
|
|
1465
|
+
walk(child, depth + 1);
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
};
|
|
1469
|
+
for (const node of nodes) {
|
|
1470
|
+
walk(node, 0);
|
|
1471
|
+
}
|
|
1472
|
+
return result;
|
|
1473
|
+
}
|
|
1474
|
+
// -------------------------------------------------------------------------
|
|
1475
|
+
// Design context parsing helpers
|
|
1476
|
+
// -------------------------------------------------------------------------
|
|
1477
|
+
/** Extract component name from generated code. */
|
|
1478
|
+
extractComponentName(code) {
|
|
1479
|
+
// Match class/component name patterns
|
|
1480
|
+
const classMatch = code.match(/class\s+(\w+)/);
|
|
1481
|
+
if (classMatch)
|
|
1482
|
+
return classMatch[1];
|
|
1483
|
+
const componentMatch = code.match(/(?:export\s+)?(?:default\s+)?(?:function|const)\s+(\w+)/);
|
|
1484
|
+
if (componentMatch)
|
|
1485
|
+
return componentMatch[1];
|
|
1486
|
+
// Try HTML custom element tag
|
|
1487
|
+
const tagMatch = code.match(/<([a-z][\w-]*)/);
|
|
1488
|
+
if (tagMatch)
|
|
1489
|
+
return tagMatch[1];
|
|
1490
|
+
return '';
|
|
1491
|
+
}
|
|
1492
|
+
/** Extract description from code comments or JSDoc. */
|
|
1493
|
+
extractDescription(code) {
|
|
1494
|
+
const jsdocMatch = code.match(/\/\*\*\s*\n?\s*\*?\s*(.+?)(?:\n|\*\/)/);
|
|
1495
|
+
if (jsdocMatch)
|
|
1496
|
+
return jsdocMatch[1].trim();
|
|
1497
|
+
const commentMatch = code.match(/\/\/\s*(.+)/);
|
|
1498
|
+
if (commentMatch)
|
|
1499
|
+
return commentMatch[1].trim();
|
|
1500
|
+
return '';
|
|
1501
|
+
}
|
|
1502
|
+
/** Extract variant definitions from code. */
|
|
1503
|
+
extractVariants(code) {
|
|
1504
|
+
const variants = [];
|
|
1505
|
+
// Match variant property patterns (e.g. variant="primary", size="large")
|
|
1506
|
+
const variantPattern = /(?:variant|type|size|state)\s*[=:]\s*["'](\w+)["']/gi;
|
|
1507
|
+
const seen = new Set();
|
|
1508
|
+
let match;
|
|
1509
|
+
while ((match = variantPattern.exec(code)) !== null) {
|
|
1510
|
+
const propName = match[0].split(/[=:]/)[0].trim().toLowerCase();
|
|
1511
|
+
const value = match[1];
|
|
1512
|
+
const key = `${propName}=${value}`;
|
|
1513
|
+
if (!seen.has(key)) {
|
|
1514
|
+
seen.add(key);
|
|
1515
|
+
variants.push({ name: key, properties: { [propName]: value } });
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
return variants;
|
|
1519
|
+
}
|
|
1520
|
+
/** Extract visual states from code (hover, focus, disabled, pressed). */
|
|
1521
|
+
extractStates(code) {
|
|
1522
|
+
const stateKeywords = ['hover', 'focus', 'disabled', 'pressed', 'active', 'selected'];
|
|
1523
|
+
const states = [];
|
|
1524
|
+
const codeLower = code.toLowerCase();
|
|
1525
|
+
for (const keyword of stateKeywords) {
|
|
1526
|
+
if (codeLower.includes(keyword)) {
|
|
1527
|
+
states.push({ name: keyword });
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
return states;
|
|
1531
|
+
}
|
|
1532
|
+
/** Extract component properties from code. */
|
|
1533
|
+
extractProperties(code) {
|
|
1534
|
+
const properties = [];
|
|
1535
|
+
// Match TypeScript interface/type property patterns
|
|
1536
|
+
const propPattern = /(\w+)\s*[?]?\s*:\s*(string|number|boolean|'[^']*'(?:\s*\|\s*'[^']*')*)/g;
|
|
1537
|
+
const seen = new Set();
|
|
1538
|
+
let match;
|
|
1539
|
+
while ((match = propPattern.exec(code)) !== null) {
|
|
1540
|
+
const name = match[1];
|
|
1541
|
+
const type = match[2];
|
|
1542
|
+
if (!seen.has(name)) {
|
|
1543
|
+
seen.add(name);
|
|
1544
|
+
properties.push({ name, type });
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
return properties;
|
|
1548
|
+
}
|
|
1549
|
+
/** Extract layout information from code. */
|
|
1550
|
+
extractLayout(code) {
|
|
1551
|
+
const codeLower = code.toLowerCase();
|
|
1552
|
+
let mode = 'none';
|
|
1553
|
+
if (codeLower.includes('flex-direction: row') || codeLower.includes('flexdirection: row') || codeLower.includes('display: flex')) {
|
|
1554
|
+
mode = 'horizontal';
|
|
1555
|
+
}
|
|
1556
|
+
if (codeLower.includes('flex-direction: column') || codeLower.includes('flexdirection: column')) {
|
|
1557
|
+
mode = 'vertical';
|
|
1558
|
+
}
|
|
1559
|
+
const layout = { mode };
|
|
1560
|
+
// Extract gap/spacing
|
|
1561
|
+
const gapMatch = code.match(/gap:\s*(\d+)/);
|
|
1562
|
+
if (gapMatch) {
|
|
1563
|
+
layout.itemSpacing = parseInt(gapMatch[1], 10);
|
|
1564
|
+
}
|
|
1565
|
+
// Extract padding
|
|
1566
|
+
const paddingMatch = code.match(/padding:\s*(\d+)(?:px)?(?:\s+(\d+)(?:px)?)?(?:\s+(\d+)(?:px)?)?(?:\s+(\d+)(?:px)?)?/);
|
|
1567
|
+
if (paddingMatch) {
|
|
1568
|
+
const values = [paddingMatch[1], paddingMatch[2], paddingMatch[3], paddingMatch[4]]
|
|
1569
|
+
.filter(Boolean)
|
|
1570
|
+
.map(Number);
|
|
1571
|
+
if (values.length === 1) {
|
|
1572
|
+
layout.padding = { top: values[0], right: values[0], bottom: values[0], left: values[0] };
|
|
1573
|
+
}
|
|
1574
|
+
else if (values.length === 2) {
|
|
1575
|
+
layout.padding = { top: values[0], right: values[1], bottom: values[0], left: values[1] };
|
|
1576
|
+
}
|
|
1577
|
+
else if (values.length === 4) {
|
|
1578
|
+
layout.padding = { top: values[0], right: values[1], bottom: values[2], left: values[3] };
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
return layout;
|
|
1582
|
+
}
|
|
1583
|
+
/** Extract states from metadata XML. */
|
|
1584
|
+
extractStatesFromMetadata(xml) {
|
|
1585
|
+
const stateKeywords = ['hover', 'focus', 'disabled', 'pressed', 'active', 'selected'];
|
|
1586
|
+
const states = [];
|
|
1587
|
+
const xmlLower = xml.toLowerCase();
|
|
1588
|
+
for (const keyword of stateKeywords) {
|
|
1589
|
+
if (xmlLower.includes(keyword)) {
|
|
1590
|
+
states.push({ name: keyword });
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
return states;
|
|
1594
|
+
}
|
|
1595
|
+
// -------------------------------------------------------------------------
|
|
1596
|
+
// readTokenBindings (Task 3.3)
|
|
1597
|
+
// -------------------------------------------------------------------------
|
|
1598
|
+
/**
|
|
1599
|
+
* Read all token bindings (Figma variables) from a file.
|
|
1600
|
+
*
|
|
1601
|
+
* Uses figma-console-mcp via `consoleMcp.getVariables()` which calls
|
|
1602
|
+
* `figma_get_token_values`. Maps results to `TokenBinding[]` with alias
|
|
1603
|
+
* detection based on `valuesByMode` containing `{ aliasOf: string }`.
|
|
1604
|
+
*
|
|
1605
|
+
* @param fileKey - The Figma file key.
|
|
1606
|
+
* @returns Array of token bindings with alias relationships detected.
|
|
1607
|
+
*/
|
|
1608
|
+
async readTokenBindings(fileKey) {
|
|
1609
|
+
const variables = await this.consoleMcp.getVariables(fileKey);
|
|
1610
|
+
if (!variables || variables.length === 0) {
|
|
1611
|
+
return [];
|
|
1612
|
+
}
|
|
1613
|
+
// Build a lookup of variable names for alias target resolution
|
|
1614
|
+
const nameById = new Map();
|
|
1615
|
+
for (const v of variables) {
|
|
1616
|
+
if (v.id) {
|
|
1617
|
+
nameById.set(v.id, v.name);
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
return variables.map((v) => {
|
|
1621
|
+
// Detect alias: valuesByMode values shaped { aliasOf: string }
|
|
1622
|
+
const { isAlias, aliasTarget } = this.detectAlias(v.valuesByMode, nameById);
|
|
1623
|
+
// collectionName is available at runtime from figma_get_token_values
|
|
1624
|
+
// even though the FigmaVariable type doesn't declare it
|
|
1625
|
+
const raw = v;
|
|
1626
|
+
const collectionName = typeof raw.collectionName === 'string'
|
|
1627
|
+
? raw.collectionName
|
|
1628
|
+
: this.inferCollectionFromName(v.name, isAlias);
|
|
1629
|
+
return {
|
|
1630
|
+
variableName: v.name,
|
|
1631
|
+
variableId: v.id ?? '',
|
|
1632
|
+
collectionName,
|
|
1633
|
+
resolvedType: v.resolvedType,
|
|
1634
|
+
valuesByMode: v.valuesByMode,
|
|
1635
|
+
isAlias,
|
|
1636
|
+
aliasTarget,
|
|
1637
|
+
};
|
|
1638
|
+
});
|
|
1639
|
+
}
|
|
1640
|
+
/**
|
|
1641
|
+
* Detect whether a variable is an alias by inspecting its mode values.
|
|
1642
|
+
*
|
|
1643
|
+
* Figma aliases are represented as `{ aliasOf: string }` in valuesByMode.
|
|
1644
|
+
* Returns the first alias target found (semantic tokens typically alias
|
|
1645
|
+
* the same primitive across all modes).
|
|
1646
|
+
*/
|
|
1647
|
+
detectAlias(valuesByMode, nameById) {
|
|
1648
|
+
for (const modeValue of Object.values(valuesByMode)) {
|
|
1649
|
+
if (modeValue &&
|
|
1650
|
+
typeof modeValue === 'object' &&
|
|
1651
|
+
'aliasOf' in modeValue) {
|
|
1652
|
+
const aliasRef = modeValue.aliasOf;
|
|
1653
|
+
// aliasOf may be a variable name or an ID — resolve via lookup
|
|
1654
|
+
const resolved = nameById.get(aliasRef) ?? aliasRef;
|
|
1655
|
+
return { isAlias: true, aliasTarget: resolved };
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
return { isAlias: false };
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Infer collection name from variable name when not provided by MCP.
|
|
1662
|
+
*
|
|
1663
|
+
* Heuristic: variables with dot-separated semantic paths (e.g.
|
|
1664
|
+
* "color.primary", "color.feedback.success.text") are Semantics;
|
|
1665
|
+
* simple group/value names (e.g. "space/100", "color/purple/300")
|
|
1666
|
+
* are Primitives.
|
|
1667
|
+
*/
|
|
1668
|
+
inferCollectionFromName(name, isAlias) {
|
|
1669
|
+
if (isAlias)
|
|
1670
|
+
return 'Semantics';
|
|
1671
|
+
// Semantic tokens use dot notation in their Figma names (pushed via 054a)
|
|
1672
|
+
// e.g. "color.primary", "color.feedback.success.text"
|
|
1673
|
+
if (name.includes('.'))
|
|
1674
|
+
return 'Semantics';
|
|
1675
|
+
// Primitive tokens use slash notation: "space/100", "color/purple/300"
|
|
1676
|
+
return 'Primitives';
|
|
1677
|
+
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Read Figma styles (effect and text) from a file via figma-console-mcp.
|
|
1680
|
+
*
|
|
1681
|
+
* Calls `consoleMcp.getStyles(fileKey)` which invokes `figma_get_styles`,
|
|
1682
|
+
* then maps results to `FigmaStyle[]`. Effect styles represent shadows/blurs;
|
|
1683
|
+
* text styles represent typography.
|
|
1684
|
+
*
|
|
1685
|
+
* @param fileKey - The Figma file key.
|
|
1686
|
+
* @returns Array of FigmaStyle objects separated by type.
|
|
1687
|
+
* @requirements Req 3 (Composite Token Reconstruction)
|
|
1688
|
+
*/
|
|
1689
|
+
async readStyles(fileKey) {
|
|
1690
|
+
const rawStyles = await this.consoleMcp.getStyles(fileKey);
|
|
1691
|
+
if (!rawStyles || rawStyles.length === 0) {
|
|
1692
|
+
return [];
|
|
1693
|
+
}
|
|
1694
|
+
return rawStyles.map((s) => ({
|
|
1695
|
+
name: s.name,
|
|
1696
|
+
type: s.type,
|
|
1697
|
+
properties: s.properties,
|
|
1698
|
+
}));
|
|
1699
|
+
}
|
|
1700
|
+
// -------------------------------------------------------------------------
|
|
1701
|
+
// queryContext (Task 3.5)
|
|
1702
|
+
// -------------------------------------------------------------------------
|
|
1703
|
+
/**
|
|
1704
|
+
* Determine the component family from a component name and query
|
|
1705
|
+
* DesignerPunk MCP for family pattern and existing component status.
|
|
1706
|
+
*
|
|
1707
|
+
* Family extraction uses PascalCase heuristics:
|
|
1708
|
+
* "ButtonCTA" → "Button"
|
|
1709
|
+
* "InputTextBase" → "Input"
|
|
1710
|
+
* "IconBase" → "Icon"
|
|
1711
|
+
* "ContainerBase" → "Container"
|
|
1712
|
+
*
|
|
1713
|
+
* Delegates to VariantAnalyzer's `queryFamilyPattern()` and
|
|
1714
|
+
* `queryExistingComponents()` for the actual MCP queries.
|
|
1715
|
+
*
|
|
1716
|
+
* @param componentName - The Figma component name (e.g. "ButtonCTA").
|
|
1717
|
+
* @returns ExtractionContext with family pattern and existing components.
|
|
1718
|
+
* @requirements Req 1 (DesignExtractor), Req 4 (Context-Aware Variant Mapping)
|
|
1719
|
+
*/
|
|
1720
|
+
async queryContext(componentName) {
|
|
1721
|
+
const familyName = this.extractFamilyName(componentName);
|
|
1722
|
+
const [familyPattern, existingComponents] = await Promise.all([
|
|
1723
|
+
this.analyzer.queryFamilyPattern(familyName),
|
|
1724
|
+
this.analyzer.queryExistingComponents(familyName),
|
|
1725
|
+
]);
|
|
1726
|
+
return { familyPattern, existingComponents };
|
|
1727
|
+
}
|
|
1728
|
+
/**
|
|
1729
|
+
* Extract the family name from a PascalCase component name.
|
|
1730
|
+
*
|
|
1731
|
+
* Splits on uppercase boundaries and returns the first segment.
|
|
1732
|
+
* Handles common suffixes like "Base", "CTA", etc.
|
|
1733
|
+
*
|
|
1734
|
+
* Examples:
|
|
1735
|
+
* "ButtonCTA" → "Button"
|
|
1736
|
+
* "InputTextBase" → "Input"
|
|
1737
|
+
* "IconBase" → "Icon"
|
|
1738
|
+
* "container-base" → "Container" (kebab-case fallback)
|
|
1739
|
+
* "Button" → "Button"
|
|
1740
|
+
*/
|
|
1741
|
+
extractFamilyName(componentName) {
|
|
1742
|
+
// Handle kebab-case (e.g. "button-cta", "input-text-base")
|
|
1743
|
+
if (componentName.includes('-')) {
|
|
1744
|
+
const first = componentName.split('-')[0];
|
|
1745
|
+
return first.charAt(0).toUpperCase() + first.slice(1).toLowerCase();
|
|
1746
|
+
}
|
|
1747
|
+
// PascalCase: split on uppercase boundaries
|
|
1748
|
+
const segments = componentName.replace(/([a-z])([A-Z])/g, '$1 $2').split(' ');
|
|
1749
|
+
return segments[0];
|
|
1750
|
+
}
|
|
1751
|
+
// -------------------------------------------------------------------------
|
|
1752
|
+
// translateTokens (Task 3.6)
|
|
1753
|
+
// -------------------------------------------------------------------------
|
|
1754
|
+
/**
|
|
1755
|
+
* Translate all component properties to DesignerPunk token references.
|
|
1756
|
+
*
|
|
1757
|
+
* Builds a binding lookup map from the token bindings, then iterates
|
|
1758
|
+
* over the component's layout, color, typography, radius, and shadow
|
|
1759
|
+
* properties. For each property, checks if a variable binding exists
|
|
1760
|
+
* and delegates to `translator.translate()` with binding-first strategy.
|
|
1761
|
+
*
|
|
1762
|
+
* Tracks no-match values for pause reporting in the extraction confidence.
|
|
1763
|
+
*
|
|
1764
|
+
* @param component - The extracted Figma component with layout and raw data.
|
|
1765
|
+
* @param bindings - Token bindings read from figma-console-mcp.
|
|
1766
|
+
* @returns Aggregated TokenUsage with all translated references.
|
|
1767
|
+
* @requirements Req 2 (TokenTranslator Implementation)
|
|
1768
|
+
*/
|
|
1769
|
+
translateTokens(component, bindings) {
|
|
1770
|
+
// Build binding lookup: variableName → TokenBinding
|
|
1771
|
+
const bindingMap = new Map();
|
|
1772
|
+
for (const binding of bindings) {
|
|
1773
|
+
bindingMap.set(binding.variableName, binding);
|
|
1774
|
+
}
|
|
1775
|
+
// Build variable ID → variable name lookup for resolving boundVariables
|
|
1776
|
+
const nameById = new Map();
|
|
1777
|
+
for (const binding of bindings) {
|
|
1778
|
+
if (binding.variableId) {
|
|
1779
|
+
nameById.set(binding.variableId, binding.variableName);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
const usage = {
|
|
1783
|
+
spacing: [],
|
|
1784
|
+
colors: [],
|
|
1785
|
+
typography: [],
|
|
1786
|
+
radius: [],
|
|
1787
|
+
shadows: [],
|
|
1788
|
+
};
|
|
1789
|
+
// --- Direct boundVariable translation (highest confidence path) ---
|
|
1790
|
+
// When Console MCP provides boundVariables from component children,
|
|
1791
|
+
// we can resolve variable IDs directly to token names without value scanning.
|
|
1792
|
+
const bvMap = component.boundVariableMap;
|
|
1793
|
+
// Track which layout properties were resolved via boundVariables so we
|
|
1794
|
+
// can fall through to value-based matching for the rest.
|
|
1795
|
+
const resolvedByBinding = new Set();
|
|
1796
|
+
if (bvMap && bvMap.size > 0) {
|
|
1797
|
+
// Mapping of Figma boundVariable property names to our categories
|
|
1798
|
+
const spacingProps = {
|
|
1799
|
+
paddingLeft: 'padding-left',
|
|
1800
|
+
paddingRight: 'padding-right',
|
|
1801
|
+
paddingTop: 'padding-top',
|
|
1802
|
+
paddingBottom: 'padding-bottom',
|
|
1803
|
+
itemSpacing: 'item-spacing',
|
|
1804
|
+
};
|
|
1805
|
+
const radiusProps = {
|
|
1806
|
+
topLeftRadius: 'border-radius-top-left',
|
|
1807
|
+
topRightRadius: 'border-radius-top-right',
|
|
1808
|
+
bottomLeftRadius: 'border-radius-bottom-left',
|
|
1809
|
+
bottomRightRadius: 'border-radius-bottom-right',
|
|
1810
|
+
cornerRadius: 'border-radius',
|
|
1811
|
+
};
|
|
1812
|
+
const colorProps = {
|
|
1813
|
+
color: 'fill',
|
|
1814
|
+
};
|
|
1815
|
+
for (const [figmaProp, varId] of bvMap) {
|
|
1816
|
+
const varName = nameById.get(varId);
|
|
1817
|
+
if (!varName)
|
|
1818
|
+
continue; // Variable ID not found in bindings
|
|
1819
|
+
const cssProperty = spacingProps[figmaProp] ?? radiusProps[figmaProp] ?? colorProps[figmaProp];
|
|
1820
|
+
if (!cssProperty)
|
|
1821
|
+
continue; // Unknown property — skip
|
|
1822
|
+
let category;
|
|
1823
|
+
if (spacingProps[figmaProp])
|
|
1824
|
+
category = 'spacing';
|
|
1825
|
+
else if (radiusProps[figmaProp])
|
|
1826
|
+
category = 'radius';
|
|
1827
|
+
else
|
|
1828
|
+
category = 'color';
|
|
1829
|
+
const result = this.translator.translate(varName, 0, category);
|
|
1830
|
+
const ref = {
|
|
1831
|
+
property: cssProperty,
|
|
1832
|
+
token: result.token,
|
|
1833
|
+
confidence: result.confidence,
|
|
1834
|
+
matchMethod: 'binding',
|
|
1835
|
+
primitive: result.primitive,
|
|
1836
|
+
semantic: result.semantic,
|
|
1837
|
+
delta: result.delta,
|
|
1838
|
+
rawValue: result.rawValue,
|
|
1839
|
+
suggestion: result.suggestion,
|
|
1840
|
+
};
|
|
1841
|
+
if (category === 'spacing') {
|
|
1842
|
+
usage.spacing.push(ref);
|
|
1843
|
+
resolvedByBinding.add(cssProperty);
|
|
1844
|
+
}
|
|
1845
|
+
else if (category === 'radius') {
|
|
1846
|
+
usage.radius.push(ref);
|
|
1847
|
+
resolvedByBinding.add(cssProperty);
|
|
1848
|
+
}
|
|
1849
|
+
else {
|
|
1850
|
+
usage.colors.push(ref);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
// --- Layout-based spacing (fills gaps not covered by boundVariables) ---
|
|
1855
|
+
// Always attempt layout-based translation for properties that weren't
|
|
1856
|
+
// resolved via direct boundVariable binding above.
|
|
1857
|
+
{
|
|
1858
|
+
const layout = component.layout;
|
|
1859
|
+
if (layout.itemSpacing != null && !resolvedByBinding.has('item-spacing')) {
|
|
1860
|
+
const ref = this.translateProperty('item-spacing', layout.itemSpacing, 'spacing', bindingMap);
|
|
1861
|
+
usage.spacing.push(ref);
|
|
1862
|
+
}
|
|
1863
|
+
if (layout.padding) {
|
|
1864
|
+
const sides = [
|
|
1865
|
+
['padding-top', layout.padding.top],
|
|
1866
|
+
['padding-right', layout.padding.right],
|
|
1867
|
+
['padding-bottom', layout.padding.bottom],
|
|
1868
|
+
['padding-left', layout.padding.left],
|
|
1869
|
+
];
|
|
1870
|
+
for (const [prop, value] of sides) {
|
|
1871
|
+
if (value != null && !resolvedByBinding.has(prop)) {
|
|
1872
|
+
usage.spacing.push(this.translateProperty(prop, value, 'spacing', bindingMap));
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
// Corner radius from structured data (when not resolved via boundVariable)
|
|
1877
|
+
if (component.cornerRadius != null && usage.radius.length === 0) {
|
|
1878
|
+
usage.radius.push(this.translateProperty('border-radius', component.cornerRadius, 'radius', bindingMap));
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
// --- Fills from structured data (when no rawDesignContext) ---
|
|
1882
|
+
if (component.fills && component.fills.length > 0 && !component.rawDesignContext) {
|
|
1883
|
+
for (const fill of component.fills) {
|
|
1884
|
+
if (fill.color) {
|
|
1885
|
+
usage.colors.push(this.translateProperty('fill', fill.color, 'color', bindingMap));
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
// --- Parse raw design context for colors, typography, radius, shadows ---
|
|
1890
|
+
const raw = component.rawDesignContext ?? '';
|
|
1891
|
+
// Colors: match CSS color properties
|
|
1892
|
+
const colorPatterns = [
|
|
1893
|
+
{ pattern: /(?:background|background-color)\s*:\s*([^;}\n]+)/gi, prop: 'background' },
|
|
1894
|
+
{ pattern: /(?:^|[^-])color\s*:\s*([^;}\n]+)/gim, prop: 'color' },
|
|
1895
|
+
{ pattern: /border-color\s*:\s*([^;}\n]+)/gi, prop: 'border-color' },
|
|
1896
|
+
{ pattern: /fill\s*:\s*([^;}\n]+)/gi, prop: 'fill' },
|
|
1897
|
+
{ pattern: /stroke\s*:\s*([^;}\n]+)/gi, prop: 'stroke' },
|
|
1898
|
+
];
|
|
1899
|
+
for (const { pattern, prop } of colorPatterns) {
|
|
1900
|
+
let match;
|
|
1901
|
+
while ((match = pattern.exec(raw)) !== null) {
|
|
1902
|
+
const value = match[1].trim();
|
|
1903
|
+
if (this.isColorValue(value)) {
|
|
1904
|
+
usage.colors.push(this.translateProperty(prop, value, 'color', bindingMap));
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
// Typography: font-size, font-family, font-weight, line-height
|
|
1909
|
+
const typographyPatterns = [
|
|
1910
|
+
{ pattern: /font-size\s*:\s*([^;}\n]+)/gi, prop: 'font-size' },
|
|
1911
|
+
{ pattern: /font-weight\s*:\s*([^;}\n]+)/gi, prop: 'font-weight' },
|
|
1912
|
+
{ pattern: /line-height\s*:\s*([^;}\n]+)/gi, prop: 'line-height' },
|
|
1913
|
+
];
|
|
1914
|
+
for (const { pattern, prop } of typographyPatterns) {
|
|
1915
|
+
let match;
|
|
1916
|
+
while ((match = pattern.exec(raw)) !== null) {
|
|
1917
|
+
const value = match[1].trim();
|
|
1918
|
+
usage.typography.push(this.translateProperty(prop, value, 'typography', bindingMap));
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
// Radius: border-radius
|
|
1922
|
+
const radiusPattern = /border-radius\s*:\s*([^;}\n]+)/gi;
|
|
1923
|
+
let radiusMatch;
|
|
1924
|
+
while ((radiusMatch = radiusPattern.exec(raw)) !== null) {
|
|
1925
|
+
const value = radiusMatch[1].trim();
|
|
1926
|
+
usage.radius.push(this.translateProperty('border-radius', value, 'radius', bindingMap));
|
|
1927
|
+
}
|
|
1928
|
+
// Shadows: box-shadow
|
|
1929
|
+
const shadowPattern = /box-shadow\s*:\s*([^;}\n]+)/gi;
|
|
1930
|
+
let shadowMatch;
|
|
1931
|
+
while ((shadowMatch = shadowPattern.exec(raw)) !== null) {
|
|
1932
|
+
const value = shadowMatch[1].trim();
|
|
1933
|
+
usage.shadows.push(this.translateProperty('box-shadow', value, 'shadow', bindingMap));
|
|
1934
|
+
}
|
|
1935
|
+
return usage;
|
|
1936
|
+
}
|
|
1937
|
+
/**
|
|
1938
|
+
* Translate a single property value to a token reference.
|
|
1939
|
+
*
|
|
1940
|
+
* Checks the binding map for a variable whose resolved value matches
|
|
1941
|
+
* the raw value, then delegates to `translator.translate()`.
|
|
1942
|
+
*/
|
|
1943
|
+
translateProperty(property, rawValue, category, bindingMap) {
|
|
1944
|
+
// Try to find a binding whose value matches this raw value
|
|
1945
|
+
const bindingName = this.findBindingForValue(rawValue, category, bindingMap);
|
|
1946
|
+
const result = this.translator.translate(bindingName, rawValue, category);
|
|
1947
|
+
return {
|
|
1948
|
+
property,
|
|
1949
|
+
token: result.token,
|
|
1950
|
+
confidence: result.confidence,
|
|
1951
|
+
matchMethod: result.matchMethod,
|
|
1952
|
+
primitive: result.primitive,
|
|
1953
|
+
semantic: result.semantic,
|
|
1954
|
+
delta: result.delta,
|
|
1955
|
+
rawValue: result.rawValue,
|
|
1956
|
+
suggestion: result.suggestion,
|
|
1957
|
+
};
|
|
1958
|
+
}
|
|
1959
|
+
/**
|
|
1960
|
+
* Find a binding variable name whose resolved value matches the given raw value.
|
|
1961
|
+
*
|
|
1962
|
+
* Searches the binding map for a variable of the matching type whose
|
|
1963
|
+
* first mode value equals the raw value. Returns the variable name
|
|
1964
|
+
* (for binding-first translation) or undefined if no binding found.
|
|
1965
|
+
*/
|
|
1966
|
+
findBindingForValue(rawValue, category, bindingMap) {
|
|
1967
|
+
const expectedType = category === 'color' ? 'COLOR' : 'FLOAT';
|
|
1968
|
+
for (const [name, binding] of bindingMap) {
|
|
1969
|
+
if (binding.resolvedType !== expectedType)
|
|
1970
|
+
continue;
|
|
1971
|
+
// Check first mode value
|
|
1972
|
+
const modeValues = Object.values(binding.valuesByMode);
|
|
1973
|
+
if (modeValues.length === 0)
|
|
1974
|
+
continue;
|
|
1975
|
+
const firstValue = modeValues[0];
|
|
1976
|
+
// Skip alias objects — they don't carry resolved values
|
|
1977
|
+
if (firstValue != null && typeof firstValue === 'object')
|
|
1978
|
+
continue;
|
|
1979
|
+
if (typeof rawValue === 'number' && firstValue === rawValue) {
|
|
1980
|
+
return name;
|
|
1981
|
+
}
|
|
1982
|
+
if (String(rawValue) === String(firstValue)) {
|
|
1983
|
+
return name;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
return undefined;
|
|
1987
|
+
}
|
|
1988
|
+
/**
|
|
1989
|
+
* Check if a CSS value looks like a color (hex, rgb, rgba, hsl, named).
|
|
1990
|
+
*/
|
|
1991
|
+
/**
|
|
1992
|
+
* Check if a CSS value looks like a color (hex, rgb, rgba, hsl, named).
|
|
1993
|
+
*/
|
|
1994
|
+
isColorValue(value) {
|
|
1995
|
+
const v = value.toLowerCase().trim();
|
|
1996
|
+
// Exclude CSS keywords and non-color values
|
|
1997
|
+
const nonColorKeywords = new Set([
|
|
1998
|
+
'inherit', 'initial', 'unset', 'revert', 'none', 'transparent',
|
|
1999
|
+
'currentcolor', 'auto', 'normal',
|
|
2000
|
+
]);
|
|
2001
|
+
if (nonColorKeywords.has(v))
|
|
2002
|
+
return false;
|
|
2003
|
+
// Exclude url(), var() (non-color), calc(), etc.
|
|
2004
|
+
if (v.startsWith('url(') || v.startsWith('calc('))
|
|
2005
|
+
return false;
|
|
2006
|
+
return (v.startsWith('#') ||
|
|
2007
|
+
v.startsWith('rgb') ||
|
|
2008
|
+
v.startsWith('hsl') ||
|
|
2009
|
+
v.startsWith('var(--color'));
|
|
2010
|
+
}
|
|
2011
|
+
// -------------------------------------------------------------------------
|
|
2012
|
+
// reconstructCompositeTokens (Task 3.7)
|
|
2013
|
+
// -------------------------------------------------------------------------
|
|
2014
|
+
/**
|
|
2015
|
+
* Reconstruct composite token references from Figma styles.
|
|
2016
|
+
*
|
|
2017
|
+
* Primary path: match style names directly to DTCG composite tokens
|
|
2018
|
+
* (names match because 054a pushed them with known names).
|
|
2019
|
+
*
|
|
2020
|
+
* Fallback path: if style name doesn't match, attempt property-by-property
|
|
2021
|
+
* reconstruction by searching the DTCG token tree for tokens whose
|
|
2022
|
+
* composite sub-values match the style's raw properties.
|
|
2023
|
+
*
|
|
2024
|
+
* Unmatched composites are flagged with ⚠️ confidence for Ada's review.
|
|
2025
|
+
*
|
|
2026
|
+
* @param styles - Figma styles read via figma-console-mcp.
|
|
2027
|
+
* @param dtcgTokens - The loaded DTCG token file for lookup.
|
|
2028
|
+
* @returns TokenReference[] with matched composite tokens.
|
|
2029
|
+
* @requirements Req 3 (Composite Token Reconstruction)
|
|
2030
|
+
*/
|
|
2031
|
+
reconstructCompositeTokens(styles, dtcgTokens) {
|
|
2032
|
+
const results = [];
|
|
2033
|
+
for (const style of styles) {
|
|
2034
|
+
const category = style.type === 'EFFECT' ? 'shadow' : 'typography';
|
|
2035
|
+
// Primary path: direct name match against DTCG token tree
|
|
2036
|
+
const directMatch = this.lookupCompositeToken(style.name, category, dtcgTokens);
|
|
2037
|
+
if (directMatch) {
|
|
2038
|
+
results.push({
|
|
2039
|
+
property: category,
|
|
2040
|
+
token: directMatch.path,
|
|
2041
|
+
confidence: 'exact',
|
|
2042
|
+
matchMethod: 'binding',
|
|
2043
|
+
primitive: directMatch.path,
|
|
2044
|
+
});
|
|
2045
|
+
continue;
|
|
2046
|
+
}
|
|
2047
|
+
// Fallback path: property-by-property reconstruction
|
|
2048
|
+
const reconstructed = this.reconstructFromProperties(style, category, dtcgTokens);
|
|
2049
|
+
if (reconstructed) {
|
|
2050
|
+
results.push(reconstructed);
|
|
2051
|
+
continue;
|
|
2052
|
+
}
|
|
2053
|
+
// No match — flag for Ada's review
|
|
2054
|
+
results.push({
|
|
2055
|
+
property: category,
|
|
2056
|
+
token: '',
|
|
2057
|
+
confidence: 'no-match',
|
|
2058
|
+
matchMethod: 'value',
|
|
2059
|
+
delta: `Unmatched ${category} style "${style.name}" — requires Ada review`,
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
return results;
|
|
2063
|
+
}
|
|
2064
|
+
/**
|
|
2065
|
+
* Look up a composite token by name in the DTCG token tree.
|
|
2066
|
+
*
|
|
2067
|
+
* Tries multiple name resolution strategies:
|
|
2068
|
+
* 1. Direct path: `{category}.{styleName}` (e.g. `shadow.elevation200`)
|
|
2069
|
+
* 2. Full style name as path (e.g. `shadow.elevation200` already dot-separated)
|
|
2070
|
+
* 3. Style name with dots converted from slashes
|
|
2071
|
+
*
|
|
2072
|
+
* @returns The token path and token object if found, or null.
|
|
2073
|
+
*/
|
|
2074
|
+
lookupCompositeToken(styleName, category, dtcgTokens) {
|
|
2075
|
+
// Strategy 1: style name already includes category prefix (e.g. "shadow.elevation200")
|
|
2076
|
+
if (styleName.startsWith(`${category}.`)) {
|
|
2077
|
+
const token = this.resolveTokenPath(styleName, dtcgTokens);
|
|
2078
|
+
if (token)
|
|
2079
|
+
return { path: styleName, token };
|
|
2080
|
+
}
|
|
2081
|
+
// Strategy 2: prepend category (e.g. "elevation200" → "shadow.elevation200")
|
|
2082
|
+
const prefixedPath = `${category}.${styleName}`;
|
|
2083
|
+
const prefixedToken = this.resolveTokenPath(prefixedPath, dtcgTokens);
|
|
2084
|
+
if (prefixedToken)
|
|
2085
|
+
return { path: prefixedPath, token: prefixedToken };
|
|
2086
|
+
// Strategy 3: convert slashes to dots and try both with and without prefix
|
|
2087
|
+
const dotName = styleName.replace(/\//g, '.');
|
|
2088
|
+
if (dotName !== styleName) {
|
|
2089
|
+
if (dotName.startsWith(`${category}.`)) {
|
|
2090
|
+
const token = this.resolveTokenPath(dotName, dtcgTokens);
|
|
2091
|
+
if (token)
|
|
2092
|
+
return { path: dotName, token };
|
|
2093
|
+
}
|
|
2094
|
+
const prefixedDot = `${category}.${dotName}`;
|
|
2095
|
+
const token = this.resolveTokenPath(prefixedDot, dtcgTokens);
|
|
2096
|
+
if (token)
|
|
2097
|
+
return { path: prefixedDot, token };
|
|
2098
|
+
}
|
|
2099
|
+
return null;
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* Resolve a dot-separated token path in the DTCG token tree.
|
|
2103
|
+
*
|
|
2104
|
+
* Walks the tree following each path segment and returns the node
|
|
2105
|
+
* if it has a `$value` (i.e. is a token, not just a group).
|
|
2106
|
+
*/
|
|
2107
|
+
resolveTokenPath(path, dtcgTokens) {
|
|
2108
|
+
const parts = path.split('.');
|
|
2109
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2110
|
+
let current = dtcgTokens;
|
|
2111
|
+
for (const part of parts) {
|
|
2112
|
+
if (current == null || typeof current !== 'object')
|
|
2113
|
+
return null;
|
|
2114
|
+
current = current[part];
|
|
2115
|
+
}
|
|
2116
|
+
if (current != null && typeof current === 'object' && '$value' in current) {
|
|
2117
|
+
return current;
|
|
2118
|
+
}
|
|
2119
|
+
return null;
|
|
2120
|
+
}
|
|
2121
|
+
/**
|
|
2122
|
+
* Attempt to reconstruct a composite token from raw style properties.
|
|
2123
|
+
*
|
|
2124
|
+
* For shadow styles: compares offsetX, offsetY, blur, spread, color
|
|
2125
|
+
* against all shadow tokens in the DTCG tree.
|
|
2126
|
+
*
|
|
2127
|
+
* For typography styles: compares fontFamily, fontSize, fontWeight,
|
|
2128
|
+
* lineHeight against all typography tokens in the DTCG tree.
|
|
2129
|
+
*
|
|
2130
|
+
* Returns an approximate-confidence match if a token's sub-values
|
|
2131
|
+
* match the style properties, or null if no reconstruction possible.
|
|
2132
|
+
*/
|
|
2133
|
+
reconstructFromProperties(style, category, dtcgTokens) {
|
|
2134
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2135
|
+
const group = dtcgTokens[category];
|
|
2136
|
+
if (!group || typeof group !== 'object')
|
|
2137
|
+
return null;
|
|
2138
|
+
const props = style.properties;
|
|
2139
|
+
let bestMatch = null;
|
|
2140
|
+
for (const [key, entry] of Object.entries(group)) {
|
|
2141
|
+
if (key.startsWith('$'))
|
|
2142
|
+
continue;
|
|
2143
|
+
if (entry == null || typeof entry !== 'object' || !('$value' in entry))
|
|
2144
|
+
continue;
|
|
2145
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2146
|
+
const tokenValue = entry.$value;
|
|
2147
|
+
if (tokenValue == null || typeof tokenValue !== 'object')
|
|
2148
|
+
continue;
|
|
2149
|
+
const score = category === 'shadow'
|
|
2150
|
+
? this.scoreShadowMatch(props, tokenValue)
|
|
2151
|
+
: this.scoreTypographyMatch(props, tokenValue);
|
|
2152
|
+
if (score > 0 && (bestMatch === null || score > bestMatch.score)) {
|
|
2153
|
+
bestMatch = { path: `${category}.${key}`, score };
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
if (bestMatch) {
|
|
2157
|
+
return {
|
|
2158
|
+
property: category,
|
|
2159
|
+
token: bestMatch.path,
|
|
2160
|
+
confidence: 'approximate',
|
|
2161
|
+
matchMethod: 'value',
|
|
2162
|
+
primitive: bestMatch.path,
|
|
2163
|
+
delta: `Reconstructed from properties (score: ${bestMatch.score}/4)`,
|
|
2164
|
+
};
|
|
2165
|
+
}
|
|
2166
|
+
return null;
|
|
2167
|
+
}
|
|
2168
|
+
/**
|
|
2169
|
+
* Score how well a Figma effect style's properties match a DTCG shadow token value.
|
|
2170
|
+
*
|
|
2171
|
+
* Compares offsetX, offsetY, blur, and spread. Each matching property
|
|
2172
|
+
* adds 1 to the score (max 4). Returns 0 if no properties match.
|
|
2173
|
+
*/
|
|
2174
|
+
scoreShadowMatch(styleProps, tokenValue) {
|
|
2175
|
+
let score = 0;
|
|
2176
|
+
const fields = ['offsetX', 'offsetY', 'blur', 'spread'];
|
|
2177
|
+
for (const field of fields) {
|
|
2178
|
+
const styleProp = styleProps[field];
|
|
2179
|
+
const tokenProp = tokenValue[field];
|
|
2180
|
+
if (styleProp == null || tokenProp == null)
|
|
2181
|
+
continue;
|
|
2182
|
+
if (this.dimensionValuesMatch(styleProp, tokenProp))
|
|
2183
|
+
score++;
|
|
2184
|
+
}
|
|
2185
|
+
return score;
|
|
2186
|
+
}
|
|
2187
|
+
/**
|
|
2188
|
+
* Score how well a Figma text style's properties match a DTCG typography token value.
|
|
2189
|
+
*
|
|
2190
|
+
* Compares fontFamily, fontSize, fontWeight, and lineHeight. Each matching
|
|
2191
|
+
* property adds 1 to the score (max 4). Returns 0 if no properties match.
|
|
2192
|
+
*/
|
|
2193
|
+
scoreTypographyMatch(styleProps, tokenValue) {
|
|
2194
|
+
let score = 0;
|
|
2195
|
+
// fontFamily: string comparison
|
|
2196
|
+
if (styleProps.fontFamily != null && tokenValue.fontFamily != null) {
|
|
2197
|
+
if (String(styleProps.fontFamily) === String(tokenValue.fontFamily))
|
|
2198
|
+
score++;
|
|
2199
|
+
}
|
|
2200
|
+
// fontSize: dimension comparison
|
|
2201
|
+
if (styleProps.fontSize != null && tokenValue.fontSize != null) {
|
|
2202
|
+
if (this.dimensionValuesMatch(styleProps.fontSize, tokenValue.fontSize))
|
|
2203
|
+
score++;
|
|
2204
|
+
}
|
|
2205
|
+
// fontWeight: numeric comparison
|
|
2206
|
+
if (styleProps.fontWeight != null && tokenValue.fontWeight != null) {
|
|
2207
|
+
if (Number(styleProps.fontWeight) === Number(tokenValue.fontWeight))
|
|
2208
|
+
score++;
|
|
2209
|
+
}
|
|
2210
|
+
// lineHeight: numeric comparison (may be unitless ratio or px)
|
|
2211
|
+
if (styleProps.lineHeight != null && tokenValue.lineHeight != null) {
|
|
2212
|
+
if (this.dimensionValuesMatch(styleProps.lineHeight, tokenValue.lineHeight))
|
|
2213
|
+
score++;
|
|
2214
|
+
}
|
|
2215
|
+
return score;
|
|
2216
|
+
}
|
|
2217
|
+
/**
|
|
2218
|
+
* Compare two dimension values that may be numbers or strings with units.
|
|
2219
|
+
*
|
|
2220
|
+
* Handles: `24` vs `"24px"`, `"16px"` vs `"16px"`, `1.5` vs `1.5`.
|
|
2221
|
+
*/
|
|
2222
|
+
dimensionValuesMatch(a, b) {
|
|
2223
|
+
// Both numeric
|
|
2224
|
+
const numA = typeof a === 'number' ? a : parseFloat(String(a));
|
|
2225
|
+
const numB = typeof b === 'number' ? b : parseFloat(String(b));
|
|
2226
|
+
if (!isNaN(numA) && !isNaN(numB)) {
|
|
2227
|
+
return numA === numB;
|
|
2228
|
+
}
|
|
2229
|
+
// String comparison as fallback
|
|
2230
|
+
return String(a) === String(b);
|
|
2231
|
+
}
|
|
2232
|
+
/**
|
|
2233
|
+
* Classify a component as interactive or static based on keyword heuristics.
|
|
2234
|
+
*
|
|
2235
|
+
* Checks the component name against known interactive and static keywords.
|
|
2236
|
+
* If both match (unlikely but possible), interactive takes precedence because
|
|
2237
|
+
* missing behavioral contracts on an interactive component is a higher risk
|
|
2238
|
+
* than unnecessary contracts on a static one.
|
|
2239
|
+
*
|
|
2240
|
+
* @param componentName - The Figma component name.
|
|
2241
|
+
* @returns 'interactive' or 'static'.
|
|
2242
|
+
*/
|
|
2243
|
+
classifyComponent(componentName) {
|
|
2244
|
+
const lower = componentName.toLowerCase();
|
|
2245
|
+
const isInteractive = DesignExtractor.INTERACTIVE_KEYWORDS.some((kw) => lower.includes(kw));
|
|
2246
|
+
if (isInteractive)
|
|
2247
|
+
return 'interactive';
|
|
2248
|
+
const isStatic = DesignExtractor.STATIC_KEYWORDS.some((kw) => lower.includes(kw));
|
|
2249
|
+
if (isStatic)
|
|
2250
|
+
return 'static';
|
|
2251
|
+
// Default: treat unknown components as interactive (safer — forces review)
|
|
2252
|
+
return 'interactive';
|
|
2253
|
+
}
|
|
2254
|
+
/**
|
|
2255
|
+
* Extract visual state names from a component's detected states.
|
|
2256
|
+
*
|
|
2257
|
+
* Filters for well-known interaction states: hover, focus, disabled, pressed,
|
|
2258
|
+
* active, selected, error, loading.
|
|
2259
|
+
*/
|
|
2260
|
+
extractVisualStates(states) {
|
|
2261
|
+
const knownStates = new Set([
|
|
2262
|
+
'hover', 'focus', 'disabled', 'pressed',
|
|
2263
|
+
'active', 'selected', 'error', 'loading',
|
|
2264
|
+
'long-press',
|
|
2265
|
+
]);
|
|
2266
|
+
return states
|
|
2267
|
+
.map((s) => s.name.toLowerCase())
|
|
2268
|
+
.filter((name) => knownStates.has(name));
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* Detect behavioral contract status for a component.
|
|
2272
|
+
*
|
|
2273
|
+
* Classifies the component as interactive or static using keyword heuristics,
|
|
2274
|
+
* extracts visual states from the Figma component, and flags missing
|
|
2275
|
+
* behavioral contracts for interactive components.
|
|
2276
|
+
*
|
|
2277
|
+
* For static components, auto-generates a "no interaction" contract.
|
|
2278
|
+
*
|
|
2279
|
+
* @param component - The extracted Figma component.
|
|
2280
|
+
* @returns BehavioralContractStatus with classification, states, and confidence.
|
|
2281
|
+
*/
|
|
2282
|
+
detectBehavioralContracts(component) {
|
|
2283
|
+
const classification = this.classifyComponent(component.name);
|
|
2284
|
+
const detectedStates = this.extractVisualStates(component.states);
|
|
2285
|
+
if (classification === 'static') {
|
|
2286
|
+
return {
|
|
2287
|
+
classification: 'static',
|
|
2288
|
+
detectedStates,
|
|
2289
|
+
contractsDefined: true,
|
|
2290
|
+
autoContract: 'No interaction — static display component',
|
|
2291
|
+
confidence: '✅',
|
|
2292
|
+
};
|
|
2293
|
+
}
|
|
2294
|
+
// Interactive component: flag missing behavioral contracts
|
|
2295
|
+
// Behavioral contracts are considered missing because Figma designs
|
|
2296
|
+
// don't encode interaction behavior — only visual states.
|
|
2297
|
+
// The actual contracts must be defined during spec review.
|
|
2298
|
+
const hasStates = detectedStates.length > 0;
|
|
2299
|
+
return {
|
|
2300
|
+
classification: 'interactive',
|
|
2301
|
+
detectedStates,
|
|
2302
|
+
contractsDefined: false,
|
|
2303
|
+
confidence: '❌',
|
|
2304
|
+
};
|
|
2305
|
+
}
|
|
2306
|
+
// -------------------------------------------------------------------------
|
|
2307
|
+
// detectPlatformParity (Task 3.9)
|
|
2308
|
+
// -------------------------------------------------------------------------
|
|
2309
|
+
/**
|
|
2310
|
+
* Detect platform-specific interactions and flag parity concerns.
|
|
2311
|
+
*
|
|
2312
|
+
* Applies heuristics to classify each detected visual state by platform
|
|
2313
|
+
* support (hover = web-only, focus = all platforms, long-press = mobile).
|
|
2314
|
+
* Optionally queries platform-implementation-guidelines.md via
|
|
2315
|
+
* DesignerPunk MCP for cross-reference validation.
|
|
2316
|
+
*
|
|
2317
|
+
* Provides decision options for platform-specific interactions:
|
|
2318
|
+
* omit on unsupported platform, map to alternative interaction, or
|
|
2319
|
+
* defer to human review.
|
|
2320
|
+
*
|
|
2321
|
+
* @param component - The extracted Figma component.
|
|
2322
|
+
* @returns PlatformParityCheck with interactions and concern status.
|
|
2323
|
+
* @requirements Req 7 (Platform Parity Detection)
|
|
2324
|
+
*/
|
|
2325
|
+
async detectPlatformParity(component) {
|
|
2326
|
+
const detectedStates = this.extractVisualStates(component.states);
|
|
2327
|
+
// Query platform guidelines for cross-reference (best-effort)
|
|
2328
|
+
let guidelinesContent = null;
|
|
2329
|
+
if (this.mcpDocs) {
|
|
2330
|
+
try {
|
|
2331
|
+
guidelinesContent = await this.mcpDocs.getSection('governance/platform-implementation-guidelines.md', 'State Management Consistency');
|
|
2332
|
+
}
|
|
2333
|
+
catch {
|
|
2334
|
+
// MCP unavailable — proceed with heuristics only
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
const interactions = [];
|
|
2338
|
+
for (const state of detectedStates) {
|
|
2339
|
+
const platforms = DesignExtractor.PLATFORM_HEURISTICS[state];
|
|
2340
|
+
if (!platforms)
|
|
2341
|
+
continue;
|
|
2342
|
+
const allPlatforms = ['web', 'ios', 'android'];
|
|
2343
|
+
const missingPlatforms = allPlatforms.filter((p) => !platforms.includes(p));
|
|
2344
|
+
// Only flag interactions that are NOT available on all platforms
|
|
2345
|
+
if (missingPlatforms.length === 0)
|
|
2346
|
+
continue;
|
|
2347
|
+
const recommendation = this.buildPlatformRecommendation(state, platforms, missingPlatforms, guidelinesContent);
|
|
2348
|
+
interactions.push({
|
|
2349
|
+
interaction: state,
|
|
2350
|
+
platforms,
|
|
2351
|
+
recommendation,
|
|
2352
|
+
});
|
|
2353
|
+
}
|
|
2354
|
+
return {
|
|
2355
|
+
interactions,
|
|
2356
|
+
hasConcerns: interactions.length > 0,
|
|
2357
|
+
};
|
|
2358
|
+
}
|
|
2359
|
+
/**
|
|
2360
|
+
* Build a recommendation string for a platform-specific interaction.
|
|
2361
|
+
*
|
|
2362
|
+
* Includes decision options for the human reviewer: omit on unsupported
|
|
2363
|
+
* platforms, map to an alternative interaction, or provide a custom
|
|
2364
|
+
* approach.
|
|
2365
|
+
*/
|
|
2366
|
+
buildPlatformRecommendation(state, supportedPlatforms, missingPlatforms, guidelinesContent) {
|
|
2367
|
+
const supported = supportedPlatforms.join(', ');
|
|
2368
|
+
const missing = missingPlatforms.join(', ');
|
|
2369
|
+
// State-specific recommendations
|
|
2370
|
+
if (state === 'hover') {
|
|
2371
|
+
return (`"${state}" is ${supported}-only (not available on ${missing}). ` +
|
|
2372
|
+
'Decision options: (a) omit hover feedback on mobile, ' +
|
|
2373
|
+
'(b) map to press/active state on mobile, ' +
|
|
2374
|
+
'(c) provide alternative visual feedback.' +
|
|
2375
|
+
(guidelinesContent ? ' Cross-referenced with platform-implementation-guidelines.md.' : ''));
|
|
2376
|
+
}
|
|
2377
|
+
if (state === 'long-press') {
|
|
2378
|
+
return (`"${state}" is ${supported}-only (not available on ${missing}). ` +
|
|
2379
|
+
'Decision options: (a) omit on web, ' +
|
|
2380
|
+
'(b) map to right-click/context menu on web, ' +
|
|
2381
|
+
'(c) provide alternative trigger.' +
|
|
2382
|
+
(guidelinesContent ? ' Cross-referenced with platform-implementation-guidelines.md.' : ''));
|
|
2383
|
+
}
|
|
2384
|
+
// Generic recommendation for other platform-limited states
|
|
2385
|
+
return (`"${state}" is available on ${supported} but not on ${missing}. ` +
|
|
2386
|
+
`Decision options: (a) omit on ${missing}, ` +
|
|
2387
|
+
'(b) map to equivalent interaction, ' +
|
|
2388
|
+
'(c) defer to human review.' +
|
|
2389
|
+
(guidelinesContent ? ' Cross-referenced with platform-implementation-guidelines.md.' : ''));
|
|
2390
|
+
}
|
|
2391
|
+
// -------------------------------------------------------------------------
|
|
2392
|
+
// detectComponentTokenDecisions (Task 3.10)
|
|
2393
|
+
// -------------------------------------------------------------------------
|
|
2394
|
+
/**
|
|
2395
|
+
* Detect repeated primitive token usage and surface component token
|
|
2396
|
+
* decision points for Ada's review.
|
|
2397
|
+
*
|
|
2398
|
+
* Scans all token categories in the usage map, groups references by
|
|
2399
|
+
* their resolved primitive token, and generates illustrative component
|
|
2400
|
+
* token suggestions for any primitive used two or more times.
|
|
2401
|
+
*
|
|
2402
|
+
* All suggestions are explicitly labeled as pending human review —
|
|
2403
|
+
* no autonomous token creation per governance.
|
|
2404
|
+
*
|
|
2405
|
+
* @param tokenUsage - Aggregated token usage from translateTokens().
|
|
2406
|
+
* @param componentName - Component name for illustrative naming.
|
|
2407
|
+
* @returns Array of decision points for Ada's review.
|
|
2408
|
+
*/
|
|
2409
|
+
detectComponentTokenDecisions(tokenUsage, componentName = 'component') {
|
|
2410
|
+
// Build a map of primitiveToken → list of property locations
|
|
2411
|
+
const usageMap = new Map();
|
|
2412
|
+
const categories = [
|
|
2413
|
+
['spacing', 'spacing'],
|
|
2414
|
+
['colors', 'color'],
|
|
2415
|
+
['typography', 'typography'],
|
|
2416
|
+
['radius', 'radius'],
|
|
2417
|
+
['shadows', 'shadow'],
|
|
2418
|
+
];
|
|
2419
|
+
for (const [category] of categories) {
|
|
2420
|
+
const refs = tokenUsage[category];
|
|
2421
|
+
for (const ref of refs) {
|
|
2422
|
+
// Only consider matched tokens (not no-match)
|
|
2423
|
+
if (ref.confidence === 'no-match')
|
|
2424
|
+
continue;
|
|
2425
|
+
// Use the primitive token if available, otherwise the main token
|
|
2426
|
+
const primitiveKey = ref.primitive ?? ref.token;
|
|
2427
|
+
if (!primitiveKey)
|
|
2428
|
+
continue;
|
|
2429
|
+
const location = ref.property;
|
|
2430
|
+
const existing = usageMap.get(primitiveKey) ?? [];
|
|
2431
|
+
existing.push(location);
|
|
2432
|
+
usageMap.set(primitiveKey, existing);
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
// Generate decisions for tokens used 2+ times
|
|
2436
|
+
const decisions = [];
|
|
2437
|
+
const baseName = this.extractComponentBaseName(componentName);
|
|
2438
|
+
for (const [primitiveToken, locations] of usageMap) {
|
|
2439
|
+
if (locations.length < 2)
|
|
2440
|
+
continue;
|
|
2441
|
+
const propertyGroup = this.inferPropertyGroup(locations);
|
|
2442
|
+
const suggestion = `${baseName}.${propertyGroup} = ${primitiveToken}`;
|
|
2443
|
+
decisions.push({
|
|
2444
|
+
primitiveToken,
|
|
2445
|
+
usageCount: locations.length,
|
|
2446
|
+
locations,
|
|
2447
|
+
illustrativeSuggestion: suggestion,
|
|
2448
|
+
rationale: `${primitiveToken} is used across ${locations.length} properties ` +
|
|
2449
|
+
`(${locations.join(', ')}). Consistent usage suggests semantic ` +
|
|
2450
|
+
`intent that could be encoded as a component token.`,
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2453
|
+
// Sort by usage count descending for prioritized review
|
|
2454
|
+
decisions.sort((a, b) => b.usageCount - a.usageCount);
|
|
2455
|
+
return decisions;
|
|
2456
|
+
}
|
|
2457
|
+
/**
|
|
2458
|
+
* Extract a short base name from a component name for illustrative
|
|
2459
|
+
* token naming.
|
|
2460
|
+
*
|
|
2461
|
+
* "ButtonCTA" → "button", "InputTextBase" → "input", "ContainerBase" → "container"
|
|
2462
|
+
*/
|
|
2463
|
+
extractComponentBaseName(componentName) {
|
|
2464
|
+
// Split PascalCase into words, take the first word, lowercase it
|
|
2465
|
+
const words = componentName.replace(/([a-z])([A-Z])/g, '$1 $2').split(/[\s_-]+/);
|
|
2466
|
+
return (words[0] ?? 'component').toLowerCase();
|
|
2467
|
+
}
|
|
2468
|
+
/**
|
|
2469
|
+
* Infer a property group name from a list of CSS property locations.
|
|
2470
|
+
*
|
|
2471
|
+
* Groups related properties into semantic names:
|
|
2472
|
+
* - padding-left, padding-right → "padding.horizontal"
|
|
2473
|
+
* - padding-top, padding-bottom → "padding.vertical"
|
|
2474
|
+
* - mixed padding → "padding"
|
|
2475
|
+
* - color, fill, background → "fill"
|
|
2476
|
+
* - border-radius → "radius"
|
|
2477
|
+
* - Otherwise uses the first property name.
|
|
2478
|
+
*/
|
|
2479
|
+
inferPropertyGroup(locations) {
|
|
2480
|
+
const normalized = locations.map(l => l.toLowerCase());
|
|
2481
|
+
// Check for padding patterns
|
|
2482
|
+
const hasPaddingLeft = normalized.some(l => l.includes('padding-left') || l.includes('padding-inline-start'));
|
|
2483
|
+
const hasPaddingRight = normalized.some(l => l.includes('padding-right') || l.includes('padding-inline-end'));
|
|
2484
|
+
const hasPaddingTop = normalized.some(l => l.includes('padding-top') || l.includes('padding-block-start'));
|
|
2485
|
+
const hasPaddingBottom = normalized.some(l => l.includes('padding-bottom') || l.includes('padding-block-end'));
|
|
2486
|
+
const allPadding = normalized.every(l => l.includes('padding'));
|
|
2487
|
+
if (allPadding) {
|
|
2488
|
+
if ((hasPaddingLeft || hasPaddingRight) && !hasPaddingTop && !hasPaddingBottom) {
|
|
2489
|
+
return 'padding.horizontal';
|
|
2490
|
+
}
|
|
2491
|
+
if ((hasPaddingTop || hasPaddingBottom) && !hasPaddingLeft && !hasPaddingRight) {
|
|
2492
|
+
return 'padding.vertical';
|
|
2493
|
+
}
|
|
2494
|
+
return 'padding';
|
|
2495
|
+
}
|
|
2496
|
+
// Check for spacing patterns (item-spacing, gap, margin)
|
|
2497
|
+
if (normalized.every(l => l.includes('spacing') || l.includes('gap') || l.includes('margin'))) {
|
|
2498
|
+
return 'spacing';
|
|
2499
|
+
}
|
|
2500
|
+
// Check for color patterns
|
|
2501
|
+
if (normalized.every(l => l.includes('color') || l.includes('fill') || l.includes('background') || l.includes('stroke'))) {
|
|
2502
|
+
return 'fill';
|
|
2503
|
+
}
|
|
2504
|
+
// Check for radius
|
|
2505
|
+
if (normalized.every(l => l.includes('radius'))) {
|
|
2506
|
+
return 'radius';
|
|
2507
|
+
}
|
|
2508
|
+
// Check for shadow
|
|
2509
|
+
if (normalized.every(l => l.includes('shadow'))) {
|
|
2510
|
+
return 'shadow';
|
|
2511
|
+
}
|
|
2512
|
+
// Check for typography
|
|
2513
|
+
if (normalized.every(l => l.includes('font') || l.includes('line-height') || l.includes('letter-spacing'))) {
|
|
2514
|
+
return 'typography';
|
|
2515
|
+
}
|
|
2516
|
+
// Fallback: use the first property, cleaned up
|
|
2517
|
+
return normalized[0]?.replace(/[^a-z0-9.]/g, '-') ?? 'token';
|
|
2518
|
+
}
|
|
2519
|
+
/**
|
|
2520
|
+
* Validate mode consistency across token bindings.
|
|
2521
|
+
*
|
|
2522
|
+
* For each binding with multiple mode values, checks whether light and
|
|
2523
|
+
* dark mode values are identical. Discrepancies are categorized:
|
|
2524
|
+
*
|
|
2525
|
+
* - **expected**: Color tokens differ by mode (light/dark theme variations).
|
|
2526
|
+
* - **unexpected**: Spacing, radius, or typography tokens differ by mode
|
|
2527
|
+
* (structural tokens should be mode-agnostic).
|
|
2528
|
+
*
|
|
2529
|
+
* @param bindings - Token bindings read from Figma.
|
|
2530
|
+
* @returns ModeValidationResult with discrepancies and a flag for unexpected ones.
|
|
2531
|
+
* @requirements Req 9 (Mode Consistency Validation)
|
|
2532
|
+
*/
|
|
2533
|
+
validateModes(bindings) {
|
|
2534
|
+
const discrepancies = [];
|
|
2535
|
+
for (const binding of bindings) {
|
|
2536
|
+
const modeEntries = Object.entries(binding.valuesByMode);
|
|
2537
|
+
// Need at least two modes to compare
|
|
2538
|
+
if (modeEntries.length < 2)
|
|
2539
|
+
continue;
|
|
2540
|
+
// Identify light and dark mode entries by key name heuristic
|
|
2541
|
+
const lightKey = modeEntries.find(([k]) => /light/i.test(k));
|
|
2542
|
+
const darkKey = modeEntries.find(([k]) => /dark/i.test(k));
|
|
2543
|
+
// If we can't identify light/dark by name, compare first two modes
|
|
2544
|
+
const [modeA, modeB] = lightKey && darkKey
|
|
2545
|
+
? [lightKey, darkKey]
|
|
2546
|
+
: [modeEntries[0], modeEntries[1]];
|
|
2547
|
+
const valueA = modeA[1];
|
|
2548
|
+
const valueB = modeB[1];
|
|
2549
|
+
// Skip alias objects — they reference other variables, not resolved values
|
|
2550
|
+
if (this.isAliasValue(valueA) || this.isAliasValue(valueB))
|
|
2551
|
+
continue;
|
|
2552
|
+
// Compare values — use JSON.stringify for deep equality of objects
|
|
2553
|
+
if (this.modeValuesEqual(valueA, valueB))
|
|
2554
|
+
continue;
|
|
2555
|
+
// Values differ — categorize the discrepancy
|
|
2556
|
+
const category = binding.resolvedType === 'COLOR' ? 'expected' : 'unexpected';
|
|
2557
|
+
discrepancies.push({
|
|
2558
|
+
variableName: binding.variableName,
|
|
2559
|
+
lightValue: valueA,
|
|
2560
|
+
darkValue: valueB,
|
|
2561
|
+
category,
|
|
2562
|
+
});
|
|
2563
|
+
}
|
|
2564
|
+
return {
|
|
2565
|
+
discrepancies,
|
|
2566
|
+
hasUnexpectedDiscrepancies: discrepancies.some(d => d.category === 'unexpected'),
|
|
2567
|
+
};
|
|
2568
|
+
}
|
|
2569
|
+
/**
|
|
2570
|
+
* Resolve variable IDs from boundVariableMap that aren't in the bindings.
|
|
2571
|
+
*
|
|
2572
|
+
* When `figma_get_token_values` (limit: 500) doesn't return all variables,
|
|
2573
|
+
* some boundVariable IDs from the component tree won't resolve in the
|
|
2574
|
+
* `nameById` lookup during `translateTokens`. This method uses
|
|
2575
|
+
* `figma_execute` with Plugin API to batch-resolve those missing IDs,
|
|
2576
|
+
* returning synthetic TokenBinding entries that can be appended to the
|
|
2577
|
+
* bindings array.
|
|
2578
|
+
*
|
|
2579
|
+
* @param fileKey - The Figma file key.
|
|
2580
|
+
* @param boundVariableMap - Property→variableId map from component extraction.
|
|
2581
|
+
* @param existingBindings - Bindings already loaded from figma_get_token_values.
|
|
2582
|
+
* @returns Additional TokenBinding entries for previously unresolved IDs.
|
|
2583
|
+
*/
|
|
2584
|
+
async resolveUnknownVariableIds(fileKey, boundVariableMap, existingBindings) {
|
|
2585
|
+
if (!boundVariableMap || boundVariableMap.size === 0)
|
|
2586
|
+
return [];
|
|
2587
|
+
// Build set of known variable IDs
|
|
2588
|
+
const knownIds = new Set();
|
|
2589
|
+
for (const binding of existingBindings) {
|
|
2590
|
+
if (binding.variableId)
|
|
2591
|
+
knownIds.add(binding.variableId);
|
|
2592
|
+
}
|
|
2593
|
+
// Collect unresolved IDs (deduplicated)
|
|
2594
|
+
const unresolvedIds = new Set();
|
|
2595
|
+
for (const varId of boundVariableMap.values()) {
|
|
2596
|
+
if (!knownIds.has(varId))
|
|
2597
|
+
unresolvedIds.add(varId);
|
|
2598
|
+
}
|
|
2599
|
+
if (unresolvedIds.size === 0)
|
|
2600
|
+
return [];
|
|
2601
|
+
// Batch-resolve via Plugin API
|
|
2602
|
+
const idsArray = [...unresolvedIds];
|
|
2603
|
+
const code = `
|
|
2604
|
+
const results = {};
|
|
2605
|
+
for (const id of ${JSON.stringify(idsArray)}) {
|
|
2606
|
+
try {
|
|
2607
|
+
const v = figma.variables.getVariableById(id);
|
|
2608
|
+
if (v) {
|
|
2609
|
+
results[id] = {
|
|
2610
|
+
name: v.name,
|
|
2611
|
+
resolvedType: v.resolvedType,
|
|
2612
|
+
id: v.id,
|
|
2613
|
+
};
|
|
2614
|
+
}
|
|
2615
|
+
} catch (e) {
|
|
2616
|
+
// Variable not found — skip
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
return results;
|
|
2620
|
+
`.trim();
|
|
2621
|
+
try {
|
|
2622
|
+
const result = await this.consoleMcp.execute(fileKey, code);
|
|
2623
|
+
// Parse the result — may be wrapped in various formats
|
|
2624
|
+
let resolved = {};
|
|
2625
|
+
if (result && typeof result === 'object') {
|
|
2626
|
+
// Handle { result: { ... } } wrapper from figma_execute
|
|
2627
|
+
const raw = result;
|
|
2628
|
+
const inner = raw.result ?? raw;
|
|
2629
|
+
if (inner && typeof inner === 'object') {
|
|
2630
|
+
resolved = inner;
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
const additionalBindings = [];
|
|
2634
|
+
for (const [varId, info] of Object.entries(resolved)) {
|
|
2635
|
+
if (!info?.name)
|
|
2636
|
+
continue;
|
|
2637
|
+
additionalBindings.push({
|
|
2638
|
+
variableName: info.name,
|
|
2639
|
+
variableId: varId,
|
|
2640
|
+
collectionName: this.inferCollectionFromName(info.name, false),
|
|
2641
|
+
resolvedType: (info.resolvedType ?? 'FLOAT'),
|
|
2642
|
+
valuesByMode: {},
|
|
2643
|
+
isAlias: false,
|
|
2644
|
+
});
|
|
2645
|
+
}
|
|
2646
|
+
return additionalBindings;
|
|
2647
|
+
}
|
|
2648
|
+
catch {
|
|
2649
|
+
// Plugin API resolution failed — return empty (value-based fallback still works)
|
|
2650
|
+
return [];
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
/**
|
|
2654
|
+
* Check whether a mode value is an alias reference (not a resolved value).
|
|
2655
|
+
*/
|
|
2656
|
+
isAliasValue(value) {
|
|
2657
|
+
return (value != null &&
|
|
2658
|
+
typeof value === 'object' &&
|
|
2659
|
+
'aliasOf' in value);
|
|
2660
|
+
}
|
|
2661
|
+
/**
|
|
2662
|
+
* Compare two mode values for equality.
|
|
2663
|
+
*
|
|
2664
|
+
* Handles primitives (number, string) directly and falls back to
|
|
2665
|
+
* JSON.stringify for object values (e.g. color objects).
|
|
2666
|
+
*/
|
|
2667
|
+
modeValuesEqual(a, b) {
|
|
2668
|
+
if (a === b)
|
|
2669
|
+
return true;
|
|
2670
|
+
if (typeof a !== typeof b)
|
|
2671
|
+
return false;
|
|
2672
|
+
if (typeof a === 'object' && a !== null && b !== null) {
|
|
2673
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
2674
|
+
}
|
|
2675
|
+
return false;
|
|
2676
|
+
}
|
|
2677
|
+
/**
|
|
2678
|
+
* Extract a Figma component and produce a ComponentAnalysis.
|
|
2679
|
+
*
|
|
2680
|
+
* Orchestrates: read component → build node tree → collect/resolve
|
|
2681
|
+
* bound variables → reclassify → detect composition patterns →
|
|
2682
|
+
* capture screenshot → gather recommendations.
|
|
2683
|
+
*/
|
|
2684
|
+
async extractComponentAnalysis(fileKey, nodeId, outputDir, fileUrl) {
|
|
2685
|
+
// 1. Read component structure, token bindings, and styles in parallel
|
|
2686
|
+
const [component, bindings, styles] = await Promise.all([
|
|
2687
|
+
this.readFigmaComponent(fileKey, nodeId),
|
|
2688
|
+
this.readTokenBindings(fileKey),
|
|
2689
|
+
this.readStyles(fileKey),
|
|
2690
|
+
]);
|
|
2691
|
+
// 2. Resolve unknown variable IDs
|
|
2692
|
+
if (component.boundVariableMap && component.boundVariableMap.size > 0) {
|
|
2693
|
+
const additional = await this.resolveUnknownVariableIds(fileKey, component.boundVariableMap, bindings);
|
|
2694
|
+
if (additional.length > 0)
|
|
2695
|
+
bindings.push(...additional);
|
|
2696
|
+
}
|
|
2697
|
+
// 3. Get raw component data for node tree building
|
|
2698
|
+
const rawComponent = await this.consoleMcp.getComponent(fileKey, nodeId);
|
|
2699
|
+
// 4. Build hierarchical node tree with per-node classification
|
|
2700
|
+
const nodeTree = this.buildNodeTree(rawComponent);
|
|
2701
|
+
// 5. Collect and resolve bound variable IDs
|
|
2702
|
+
const boundEntries = this.collectBoundVariableIds(rawComponent);
|
|
2703
|
+
const { resolved, unresolvedBindings } = await this.batchResolveBoundVariables(fileKey, boundEntries);
|
|
2704
|
+
// 6. Reclassify unidentified values using resolved bindings
|
|
2705
|
+
this.reclassifyWithResolvedBindings(nodeTree, resolved);
|
|
2706
|
+
// 7. Aggregate classification counts
|
|
2707
|
+
const classificationSummary = this.aggregateClassifications(nodeTree);
|
|
2708
|
+
// 8. Detect composition patterns
|
|
2709
|
+
const compositionPatterns = this.detectCompositionPatterns(nodeTree);
|
|
2710
|
+
// 9. Capture screenshots (variants for COMPONENT_SET, single for others)
|
|
2711
|
+
const screenshots = [];
|
|
2712
|
+
const screenshotUrl = fileUrl ?? `https://www.figma.com/design/${fileKey}`;
|
|
2713
|
+
if (nodeTree.type === 'COMPONENT_SET' && nodeTree.children.length > 0) {
|
|
2714
|
+
for (const child of nodeTree.children) {
|
|
2715
|
+
const shot = await this.captureComponentScreenshot(screenshotUrl, child.id, outputDir, component.name, child.name);
|
|
2716
|
+
if (shot)
|
|
2717
|
+
screenshots.push(shot);
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
else {
|
|
2721
|
+
const shot = await this.captureComponentScreenshot(screenshotUrl, nodeId, outputDir, component.name);
|
|
2722
|
+
if (shot)
|
|
2723
|
+
screenshots.push(shot);
|
|
2724
|
+
}
|
|
2725
|
+
// 10. Gather recommendations (reuse existing methods)
|
|
2726
|
+
const tokenUsage = this.translateTokens(component, bindings);
|
|
2727
|
+
const compositeTokens = this.reconstructCompositeTokens(styles, this.translator.getDtcgTokens());
|
|
2728
|
+
for (const ref of compositeTokens) {
|
|
2729
|
+
if (ref.property === 'shadow')
|
|
2730
|
+
tokenUsage.shadows.push(ref);
|
|
2731
|
+
else if (ref.property === 'typography')
|
|
2732
|
+
tokenUsage.typography.push(ref);
|
|
2733
|
+
}
|
|
2734
|
+
const context = await this.queryContext(component.name);
|
|
2735
|
+
const analyzerComponent = {
|
|
2736
|
+
name: component.name,
|
|
2737
|
+
description: component.description,
|
|
2738
|
+
variants: component.variants.map(v => ({ name: v.name, properties: v.properties })),
|
|
2739
|
+
states: component.states.map(s => s.name),
|
|
2740
|
+
};
|
|
2741
|
+
const variantMapping = await this.analyzer.analyzeVariants(analyzerComponent, context);
|
|
2742
|
+
const componentTokens = this.detectComponentTokenDecisions(tokenUsage, component.name);
|
|
2743
|
+
const modeValidation = this.validateModes(bindings);
|
|
2744
|
+
const platformParity = await this.detectPlatformParity(component);
|
|
2745
|
+
// 11. Build variant definitions from raw response
|
|
2746
|
+
const variantDefinitions = this.buildVariantDefinitions(rawComponent);
|
|
2747
|
+
// 12. Determine component type
|
|
2748
|
+
const componentType = this.resolveComponentType(rawComponent);
|
|
2749
|
+
return {
|
|
2750
|
+
componentName: component.name,
|
|
2751
|
+
componentType,
|
|
2752
|
+
figmaId: nodeId,
|
|
2753
|
+
fileKey,
|
|
2754
|
+
variantDefinitions: Object.keys(variantDefinitions).length > 0 ? variantDefinitions : undefined,
|
|
2755
|
+
nodeTree,
|
|
2756
|
+
classificationSummary,
|
|
2757
|
+
compositionPatterns,
|
|
2758
|
+
unresolvedBindings,
|
|
2759
|
+
recommendations: {
|
|
2760
|
+
variantMapping: variantMapping.recommendations.length > 0 || variantMapping.conflicts.length > 0 ? variantMapping : undefined,
|
|
2761
|
+
componentTokens: componentTokens.length > 0 ? componentTokens : undefined,
|
|
2762
|
+
modeValidation: modeValidation.hasUnexpectedDiscrepancies ? modeValidation : undefined,
|
|
2763
|
+
platformParity: platformParity.hasConcerns ? platformParity : undefined,
|
|
2764
|
+
},
|
|
2765
|
+
screenshots,
|
|
2766
|
+
extractedAt: new Date().toISOString(),
|
|
2767
|
+
extractorVersion: '6.3.0',
|
|
2768
|
+
};
|
|
2769
|
+
}
|
|
2770
|
+
/** Aggregate classification counts across all nodes in a tree. */
|
|
2771
|
+
aggregateClassifications(node) {
|
|
2772
|
+
let semantic = node.tokenClassifications.semanticIdentified.length;
|
|
2773
|
+
let primitive = node.tokenClassifications.primitiveIdentified.length;
|
|
2774
|
+
let unidentified = node.tokenClassifications.unidentified.length;
|
|
2775
|
+
for (const child of node.children) {
|
|
2776
|
+
const c = this.aggregateClassifications(child);
|
|
2777
|
+
semantic += c.semanticIdentified;
|
|
2778
|
+
primitive += c.primitiveIdentified;
|
|
2779
|
+
unidentified += c.unidentified;
|
|
2780
|
+
}
|
|
2781
|
+
return { semanticIdentified: semantic, primitiveIdentified: primitive, unidentified };
|
|
2782
|
+
}
|
|
2783
|
+
/** Build variantDefinitions from raw Figma component response. */
|
|
2784
|
+
buildVariantDefinitions(raw) {
|
|
2785
|
+
const defs = {};
|
|
2786
|
+
const vp = raw.variantProperties;
|
|
2787
|
+
if (vp) {
|
|
2788
|
+
for (const [name, options] of Object.entries(vp)) {
|
|
2789
|
+
defs[name] = { type: 'VARIANT', defaultValue: options[0] ?? '', variantOptions: options };
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
return defs;
|
|
2793
|
+
}
|
|
2794
|
+
/** Resolve component type from raw Figma response. */
|
|
2795
|
+
resolveComponentType(raw) {
|
|
2796
|
+
const t = raw.type;
|
|
2797
|
+
if (t === 'COMPONENT_SET' || t === 'COMPONENT' || t === 'INSTANCE')
|
|
2798
|
+
return t;
|
|
2799
|
+
// If it has variantProperties, it's a COMPONENT_SET
|
|
2800
|
+
if (raw.variantProperties)
|
|
2801
|
+
return 'COMPONENT_SET';
|
|
2802
|
+
return 'COMPONENT';
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
exports.DesignExtractor = DesignExtractor;
|
|
2806
|
+
/** Platform-interaction heuristics: interaction → supported platforms. */
|
|
2807
|
+
DesignExtractor.PLATFORM_HEURISTICS = {
|
|
2808
|
+
hover: ['web'],
|
|
2809
|
+
focus: ['web', 'ios', 'android'],
|
|
2810
|
+
pressed: ['web', 'ios', 'android'],
|
|
2811
|
+
disabled: ['web', 'ios', 'android'],
|
|
2812
|
+
active: ['web', 'ios', 'android'],
|
|
2813
|
+
selected: ['web', 'ios', 'android'],
|
|
2814
|
+
'long-press': ['ios', 'android'],
|
|
2815
|
+
loading: ['web', 'ios', 'android'],
|
|
2816
|
+
error: ['web', 'ios', 'android'],
|
|
2817
|
+
};
|
|
2818
|
+
// ---------------------------------------------------------------------------
|
|
2819
|
+
// Behavioral contract detection (Task 3.8)
|
|
2820
|
+
// ---------------------------------------------------------------------------
|
|
2821
|
+
/**
|
|
2822
|
+
* Keywords that indicate an interactive component requiring behavioral contracts.
|
|
2823
|
+
* Matched case-insensitively against the component name.
|
|
2824
|
+
*/
|
|
2825
|
+
DesignExtractor.INTERACTIVE_KEYWORDS = [
|
|
2826
|
+
'button', 'input', 'toggle', 'switch', 'checkbox', 'radio',
|
|
2827
|
+
'select', 'dropdown', 'slider', 'tab', 'link', 'menu',
|
|
2828
|
+
'dialog', 'modal', 'tooltip', 'popover', 'accordion',
|
|
2829
|
+
];
|
|
2830
|
+
/**
|
|
2831
|
+
* Keywords that indicate a static (non-interactive) component.
|
|
2832
|
+
* Matched case-insensitively against the component name.
|
|
2833
|
+
*/
|
|
2834
|
+
DesignExtractor.STATIC_KEYWORDS = [
|
|
2835
|
+
'badge', 'divider', 'icon', 'avatar', 'label', 'tag',
|
|
2836
|
+
'separator', 'spacer', 'image', 'logo', 'progress',
|
|
2837
|
+
];
|
|
2838
|
+
//# sourceMappingURL=DesignExtractor.js.map
|