@3fn/core 13.0.0 → 14.1.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 +80 -132
- package/.kiro/agents/ada-prompt.md.attribution.json +45 -0
- package/.kiro/agents/ada.json +44 -59
- package/.kiro/agents/ada.json.attribution.json +13 -0
- package/.kiro/agents/data-prompt.md +83 -74
- package/.kiro/agents/data-prompt.md.attribution.json +53 -0
- package/.kiro/agents/data.json +31 -38
- package/.kiro/agents/data.json.attribution.json +13 -0
- package/.kiro/agents/kenya-prompt.md +83 -72
- package/.kiro/agents/kenya-prompt.md.attribution.json +53 -0
- package/.kiro/agents/kenya.json +27 -35
- package/.kiro/agents/kenya.json.attribution.json +13 -0
- package/.kiro/agents/leonardo-prompt.md +176 -234
- package/.kiro/agents/leonardo-prompt.md.attribution.json +45 -0
- package/.kiro/agents/leonardo.json +28 -36
- package/.kiro/agents/leonardo.json.attribution.json +13 -0
- package/.kiro/agents/lina-prompt.md +110 -151
- package/.kiro/agents/lina-prompt.md.attribution.json +53 -0
- package/.kiro/agents/lina.json +46 -59
- package/.kiro/agents/lina.json.attribution.json +13 -0
- package/.kiro/agents/sparky-prompt.md +89 -72
- package/.kiro/agents/sparky-prompt.md.attribution.json +53 -0
- package/.kiro/agents/sparky.json +37 -37
- package/.kiro/agents/sparky.json.attribution.json +13 -0
- package/.kiro/agents/stacy-prompt.md +74 -48
- package/.kiro/agents/stacy-prompt.md.attribution.json +45 -0
- package/.kiro/agents/stacy.json +28 -30
- package/.kiro/agents/stacy.json.attribution.json +13 -0
- package/.kiro/agents/thurgood-prompt.md +94 -138
- package/.kiro/agents/thurgood-prompt.md.attribution.json +45 -0
- package/.kiro/agents/thurgood.json +31 -35
- package/.kiro/agents/thurgood.json.attribution.json +13 -0
- package/.kiro/steering/AI-Collaboration-Principles.md +3 -3
- package/.kiro/steering/Civitas-System-Overview.md +7 -16
- package/.kiro/steering/DesignerPunk-Systems-Overview.md +6 -6
- package/.kiro/steering/Spec-Feedback-Protocol.md +2 -11
- package/.kiro/steering/Task-Completion-Protocol.md +98 -17
- package/.kiro/steering/core-goals.md +3 -3
- package/.kiro/steering/personal-note.md +1 -1
- package/.kiro/steering/start-up-tasks.md +17 -6
- package/application-mcp-server/src/index.ts +26 -0
- package/dist/ComponentTokens.android.kt +12 -12
- package/dist/ComponentTokens.ios.swift +12 -12
- package/dist/ComponentTokens.web.css +3 -3
- package/dist/DesignTokens.android.kt +1 -1
- package/dist/DesignTokens.dtcg.json +8 -5
- package/dist/DesignTokens.figma.json +2 -2
- package/dist/DesignTokens.ios.swift +1 -1
- package/dist/DesignTokens.web.css +1 -1
- package/dist/android/DesignTokens.android.kt +1 -1
- package/dist/blend/OklchBlendCalculator.js +1 -0
- package/dist/blend/ThemeAwareBlendUtilities.web.d.ts +13 -2
- package/dist/blend/ThemeAwareBlendUtilities.web.js +6 -1
- package/dist/browser/designerpunk.esm.js +36 -90
- package/dist/browser/designerpunk.esm.min.js +33 -36
- package/dist/browser/designerpunk.umd.js +36 -90
- package/dist/browser/designerpunk.umd.min.js +47 -50
- package/dist/browser/tokens.css +3 -3
- package/dist/build/tokens/defineComponentTokens.d.ts +10 -0
- package/dist/build/tokens/defineComponentTokens.js +26 -0
- package/dist/components/core/Avatar-Base/avatar.tokens.d.ts +21 -26
- package/dist/components/core/Avatar-Base/avatar.tokens.js +31 -34
- package/dist/components/core/Avatar-Base/index.d.ts +1 -1
- package/dist/components/core/Avatar-Base/index.js +2 -2
- package/dist/components/core/Avatar-Base/platforms/web/Avatar.web.js +24 -5
- package/dist/components/core/Button-CTA/examples/BasicUsage.d.ts +16 -28
- package/dist/components/core/Button-CTA/examples/BasicUsage.js +18 -43
- package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.d.ts +3 -15
- package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.js +9 -58
- package/dist/components/core/Button-CTA/types.d.ts +0 -24
- package/dist/components/core/Button-CTA/types.js +6 -0
- package/dist/components/core/Button-Icon/buttonIcon.tokens.d.ts +28 -14
- package/dist/components/core/Button-Icon/buttonIcon.tokens.js +35 -20
- package/dist/components/core/Input-Text-Base/types.d.ts +13 -1
- package/dist/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.js +11 -2
- package/dist/generators/DTCGFormatGenerator.js +8 -0
- package/dist/generators/TokenFileGenerator.js +7 -2
- package/dist/integration/BuildErrorHandler.js +2 -2
- package/dist/ios/DesignTokens.ios.swift +1 -1
- package/dist/mcp/application-mcp.js +24 -0
- package/dist/mcp/docs-mcp.js +130 -15
- package/dist/mcp/product-mcp.js +25 -0
- package/dist/tokens/OpacityTokens.js +1 -1
- package/dist/tokens/component/progress.d.ts +65 -5
- package/dist/tokens/component/progress.js +79 -18
- package/dist/tokens/semantic/BlendTokens.d.ts +10 -3
- package/dist/tokens/semantic/BlendTokens.js +17 -5
- package/dist/tokens/semantic/OpacityTokens.d.ts +4 -4
- package/dist/tokens/semantic/OpacityTokens.js +4 -4
- package/dist/types/ComponentTypes.d.ts +1 -1
- package/dist/types/generated/TokenTypes.d.ts +1 -1
- package/dist/types/generated/TokenTypes.js +1 -1
- package/dist/validators/StemmaTokenUsageValidator.js +3 -2
- package/dist/web/DesignTokens.web.css +1 -1
- package/governance/BUILD-SYSTEM-SETUP.md +1 -2
- package/governance/Component-Development-Guide.md +23 -13
- package/governance/Component-Development-Standards.md +21 -20
- package/governance/Component-Family-Avatar.md +6 -7
- package/governance/Component-Family-Badge.md +19 -20
- package/governance/Component-Family-Button.md +30 -43
- package/governance/Component-Family-Chip.md +14 -15
- package/governance/Component-Family-Container.md +12 -13
- package/governance/Component-Family-Data-Display.md +1 -2
- package/governance/Component-Family-Divider.md +1 -2
- package/governance/Component-Family-Form-Inputs.md +65 -65
- package/governance/Component-Family-Icon.md +9 -10
- package/governance/Component-Family-Loading.md +1 -2
- package/governance/Component-Family-Modal.md +1 -2
- package/governance/Component-Family-Navigation.md +1 -2
- package/governance/Component-Family-Progress.md +0 -1
- package/governance/Component-Inheritance-Structures.md +219 -99
- package/governance/Component-MCP-Document-Template.md +6 -5
- package/governance/Component-Primitive-vs-Semantic-Philosophy.md +1 -1
- package/governance/Component-Quick-Reference.md +33 -33
- package/governance/Component-Readiness-Status.md +59 -44
- package/governance/Component-Templates.md +57 -61
- package/governance/Contract-System-Reference.md +7 -7
- package/governance/MCP-Integration-Guide.md +1 -1
- package/governance/Process-Cross-Reference-Standards.md +31 -13
- package/governance/Process-Development-Workflow.md +49 -59
- package/governance/Process-File-Organization.md +25 -28
- package/governance/Process-Hook-Operations.md +22 -11
- package/governance/Process-Orchestration-Model-Selection.md +92 -0
- package/governance/Process-Spec-Planning.md +98 -52
- package/governance/Process-Task-Type-Definitions.md +80 -4
- package/governance/Product-Handoff-Protocol.md +2 -0
- package/governance/Rosetta-System-Architecture.md +13 -11
- package/governance/Test-Behavioral-Contract-Validation.md +38 -31
- package/governance/Test-Failure-Audit-Methodology.md +1 -1
- package/governance/Token-Family-Accessibility.md +1 -2
- package/governance/Token-Family-Blend.md +18 -16
- package/governance/Token-Family-Blur.md +0 -1
- package/governance/Token-Family-Border.md +1 -2
- package/governance/Token-Family-Color.md +0 -1
- package/governance/Token-Family-Glow.md +1 -2
- package/governance/Token-Family-Layering.md +0 -1
- package/governance/Token-Family-Motion.md +1 -2
- package/governance/Token-Family-Opacity.md +0 -1
- package/governance/Token-Family-Radius.md +1 -2
- package/governance/Token-Family-Responsive.md +1 -2
- package/governance/Token-Family-Shadow.md +1 -2
- package/governance/Token-Family-Sizing.md +0 -1
- package/governance/Token-Family-Spacing.md +1 -2
- package/governance/Token-Family-Typography.md +1 -2
- package/governance/Token-Governance.md +8 -8
- package/governance/Token-Quick-Reference.md +47 -34
- package/governance/Token-Resolution-Patterns.md +1 -1
- package/governance/Token-Semantic-Structure.md +1 -1
- package/governance/Web-Authoring-Standards.md +5 -5
- package/governance/browser-distribution-guide.md +1 -4
- package/governance/classification-map.md +474 -0
- package/governance/completion-documentation-guide.md +23 -37
- package/governance/component-meta-authoring-guide.md +1 -1
- package/governance/cross-platform-vs-platform-specific-decision-framework.md +1 -1
- package/governance/platform-implementation-guidelines.md +2 -3
- package/governance/release-management-system.md +28 -63
- package/governance/rosetta-system-principles.md +8 -6
- package/governance/stemma-system-principles.md +18 -17
- package/mcp-server/src/index.ts +24 -6
- package/mcp-server/src/indexer/DocumentIndexer.ts +119 -9
- package/mcp-server/src/indexer/__tests__/bare-id-crossrefs.test.ts +250 -0
- package/mcp-server/src/indexer/cross-ref-parser.ts +29 -1
- package/mcp-server/src/indexer/index-health.ts +27 -2
- package/mcp-server/src/query/__tests__/find-docs-calibration.test.ts +11 -26
- package/mcp-server/src/relocation-integrity-gate/__tests__/relocation-integrity-gate.test.ts +72 -5
- package/mcp-server/src/relocation-integrity-gate/relocation-integrity-gate.ts +81 -24
- package/mcp-server/src/tools/list-cross-references.ts +2 -2
- package/package.json +24 -26
- package/src/__tests__/browser-distribution/css-bundling.test.ts +6 -4
- package/src/__tests__/console-allowlist.json +14 -0
- package/src/__tests__/console-fail-setup.ts +169 -0
- package/src/__tests__/integration/Spec107-DesignLanguageContext.test.ts +16 -0
- package/src/__tests__/stemma-system/behavioral-contract-validation.test.ts +70 -17
- package/src/__tests__/stemma-system/contract-catalog-name-validation.test.ts +28 -0
- package/src/__tests__/stemma-system/form-inputs-contracts.test.ts +223 -16
- package/src/__tests__/stemma-system/input-text-native-base-call-alignment.test.ts +298 -0
- package/src/blend/OklchBlendCalculator.ts +3 -0
- package/src/blend/ThemeAwareBlendUtilities.android.kt +3 -0
- package/src/blend/ThemeAwareBlendUtilities.ios.swift +3 -0
- package/src/blend/ThemeAwareBlendUtilities.web.ts +9 -1
- package/src/blend/__tests__/InteractionStateAudit.test.ts +12 -9
- package/src/build/errors/__tests__/ErrorHandler.integration.test.ts +8 -0
- package/src/build/errors/__tests__/ErrorHandler.test.ts +5 -0
- package/src/build/tokens/__tests__/defineComponentTokens.test.ts +113 -0
- package/src/build/tokens/defineComponentTokens.ts +43 -1
- package/src/build/workflow/__tests__/CICDIntegration.test.ts +12 -1
- package/src/cli/__tests__/init.test.ts +45 -11
- package/src/components/core/Avatar-Base/Avatar-Base.schema.yaml +1 -1
- package/src/components/core/Avatar-Base/__tests__/Avatar.accessibility.test.ts +121 -7
- package/src/components/core/Avatar-Base/__tests__/Avatar.image.test.ts +3 -0
- package/src/components/core/Avatar-Base/__tests__/Avatar.test.ts +15 -6
- package/src/components/core/Avatar-Base/avatar.tokens.ts +31 -34
- package/src/components/core/Avatar-Base/contracts.yaml +11 -1
- package/src/components/core/Avatar-Base/index.ts +1 -1
- package/src/components/core/Avatar-Base/platforms/web/Avatar.web.ts +24 -5
- package/src/components/core/Badge-Count-Base/contracts.yaml +1 -1
- package/src/components/core/Badge-Label-Base/contracts.yaml +1 -1
- package/src/components/core/Button-CTA/Button-CTA.schema.yaml +2 -12
- package/src/components/core/Button-CTA/README.md +3 -6
- package/src/components/core/Button-CTA/__tests__/ButtonCTA.test.ts +35 -89
- package/src/components/core/Button-CTA/__tests__/setup.test.ts +0 -2
- package/src/components/core/Button-CTA/__tests__/test-utils.ts +0 -2
- package/src/components/core/Button-CTA/contracts.yaml +6 -29
- package/src/components/core/Button-CTA/examples/BasicUsage.html +2 -14
- package/src/components/core/Button-CTA/examples/BasicUsage.tsx +17 -44
- package/src/components/core/Button-CTA/platforms/android/ButtonCTA.android.kt +12 -20
- package/src/components/core/Button-CTA/platforms/ios/ButtonCTA.ios.swift +12 -51
- package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.css +2 -26
- package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.ts +18 -71
- package/src/components/core/Button-CTA/types.ts +10 -28
- package/src/components/core/Button-Icon/buttonIcon.tokens.ts +43 -27
- package/src/components/core/Chip-Base/__tests__/ChipBase.test.ts +13 -0
- package/src/components/core/Chip-Filter/__tests__/ChipFilter.test.ts +13 -0
- package/src/components/core/Chip-Input/__tests__/ChipInput.test.ts +13 -0
- package/src/components/core/Input-Text-Base/Input-Text-Base.schema.yaml +30 -2
- package/src/components/core/Input-Text-Base/README.md +25 -2
- package/src/components/core/Input-Text-Base/__tests__/focusIndicators.test.ts +16 -15
- package/src/components/core/Input-Text-Base/contracts.yaml +90 -0
- package/src/components/core/Input-Text-Base/platforms/android/InputTextBase.android.kt +26 -12
- package/src/components/core/Input-Text-Base/platforms/ios/InputTextBase.ios.swift +195 -59
- package/src/components/core/Input-Text-Base/types.ts +13 -1
- package/src/components/core/Input-Text-Email/Input-Text-Email.schema.yaml +5 -1
- package/src/components/core/Input-Text-Email/README.md +8 -7
- package/src/components/core/Input-Text-Email/platforms/android/InputTextEmail.android.kt +1 -4
- package/src/components/core/Input-Text-Email/platforms/ios/InputTextEmail.ios.swift +2 -16
- package/src/components/core/Input-Text-Password/Input-Text-Password.schema.yaml +10 -3
- package/src/components/core/Input-Text-Password/README.md +9 -8
- package/src/components/core/Input-Text-Password/contracts.yaml +5 -0
- package/src/components/core/Input-Text-Password/platforms/android/InputTextPassword.android.kt +17 -7
- package/src/components/core/Input-Text-Password/platforms/ios/InputTextPassword.ios.swift +22 -20
- package/src/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.ts +11 -2
- package/src/components/core/Input-Text-PhoneNumber/Input-Text-PhoneNumber.schema.yaml +5 -1
- package/src/components/core/Input-Text-PhoneNumber/README.md +9 -8
- package/src/components/core/Input-Text-PhoneNumber/platforms/android/InputTextPhoneNumber.android.kt +2 -5
- package/src/components/core/Input-Text-PhoneNumber/platforms/ios/InputTextPhoneNumber.ios.swift +3 -17
- package/src/components/core/Nav-Header-App/contracts.yaml +1 -1
- package/src/components/core/Nav-SegmentedChoice-Base/contracts.yaml +1 -1
- package/src/components/core/Progress-Indicator-Connector-Base/contracts.yaml +1 -1
- package/src/components/core/Progress-Indicator-Label-Base/contracts.yaml +1 -1
- package/src/components/core/Progress-Indicator-Node-Base/contracts.yaml +1 -1
- package/src/components/core/Progress-Stepper-Base/__tests__/StepperBase.test.ts +5 -2
- package/src/components/core/Progress-Stepper-Detailed/__tests__/StepperDetailed.test.ts +5 -2
- package/src/generators/DTCGFormatGenerator.ts +6 -0
- package/src/generators/TokenFileGenerator.ts +7 -2
- package/src/generators/__tests__/DTCGConfigOptions.test.ts +14 -5
- package/src/integration/BuildErrorHandler.ts +2 -2
- package/src/tokens/OpacityTokens.ts +1 -1
- package/src/tokens/__tests__/OpacityTokens.test.ts +3 -1
- package/src/tokens/__tests__/ProgressTokenCompliance.test.ts +5 -3
- package/src/tokens/__tests__/ProgressTokenFormulas.test.ts +11 -11
- package/src/tokens/__tests__/ProgressTokenTranslation.test.ts +22 -20
- package/src/tokens/component/progress.ts +83 -21
- package/src/tokens/semantic/BlendTokens.ts +26 -5
- package/src/tokens/semantic/OpacityTokens.ts +4 -4
- package/src/types/ComponentTypes.ts +1 -1
- package/src/types/generated/TokenTypes.ts +1 -1
- package/src/validators/StemmaTokenUsageValidator.ts +3 -2
- package/token-index/components.yaml +8 -8
- package/token-index/semantics.yaml +1 -2
- package/src/tools/release/__tests__/ChangeClassifier.test.ts +0 -133
- package/src/tools/release/__tests__/ChangeExtractor.test.ts +0 -222
- package/src/tools/release/__tests__/GitHubPublisher.test.ts +0 -240
- package/src/tools/release/__tests__/NotesRenderer.test.ts +0 -142
- package/src/tools/release/__tests__/NpmPublisher.test.ts +0 -289
- package/src/tools/release/__tests__/PipelineIntegration.test.ts +0 -188
- package/src/tools/release/__tests__/ReleasePipeline.test.ts +0 -192
- package/src/tools/release/__tests__/SemanticVersionValidator.test.ts +0 -49
- package/src/tools/release/__tests__/SummaryScanner.test.ts +0 -141
- package/src/tools/release/__tests__/TagResolver.test.ts +0 -91
- package/src/tools/release/__tests__/VersionCalculator.test.ts +0 -270
- package/src/tools/release/__tests__/helpers/NpmMockHelper.ts +0 -80
- package/src/tools/release/cli/ReleasePipeline.ts +0 -165
- package/src/tools/release/cli/release-tool.ts +0 -107
- package/src/tools/release/pipeline/ChangeClassifier.ts +0 -61
- package/src/tools/release/pipeline/ChangeExtractor.ts +0 -87
- package/src/tools/release/pipeline/NotesRenderer.ts +0 -66
- package/src/tools/release/pipeline/SummaryScanner.ts +0 -70
- package/src/tools/release/pipeline/TagResolver.ts +0 -40
- package/src/tools/release/pipeline/VersionCalculator.ts +0 -375
- package/src/tools/release/publishers/GitHubPublisher.ts +0 -228
- package/src/tools/release/publishers/NpmPublisher.ts +0 -196
- package/src/tools/release/release-config.json +0 -5
- package/src/tools/release/types/index.ts +0 -282
- package/src/tools/release/validators/SemanticVersionValidator.ts +0 -67
|
@@ -18,13 +18,15 @@
|
|
|
18
18
|
|
|
19
19
|
import { TokenFileGenerator } from '../../generators/TokenFileGenerator';
|
|
20
20
|
import { ComponentTokenRegistry } from '../../registries/ComponentTokenRegistry';
|
|
21
|
-
import { getTokenContract } from '../../build/tokens';
|
|
22
21
|
|
|
23
22
|
// Spec 124: defineComponentTokens no longer self-registers; the rich tokens ride back on
|
|
24
|
-
// the branded return. We reproduce the production harvest here (recover
|
|
23
|
+
// the branded return. We reproduce the production harvest here (recover the rich tokens
|
|
25
24
|
// + register into the canonical registry) so the real TokenFileGenerator pipeline — which
|
|
26
25
|
// reads ComponentTokenRegistry.getAll() — has the Progress tokens to translate.
|
|
27
|
-
|
|
26
|
+
//
|
|
27
|
+
// Progress registers through THREE family calls (sizing / spacing / borderWidth), so the
|
|
28
|
+
// harvest is the concatenation helper rather than getTokenContract() of a single export.
|
|
29
|
+
import { getProgressRegisteredTokens } from '../../tokens/component/progress';
|
|
28
30
|
|
|
29
31
|
describe('Progress Token Cross-Platform Translation', () => {
|
|
30
32
|
let generator: TokenFileGenerator;
|
|
@@ -34,7 +36,7 @@ describe('Progress Token Cross-Platform Translation', () => {
|
|
|
34
36
|
|
|
35
37
|
beforeAll(() => {
|
|
36
38
|
ComponentTokenRegistry.clear();
|
|
37
|
-
for (const token of
|
|
39
|
+
for (const token of getProgressRegisteredTokens()) {
|
|
38
40
|
ComponentTokenRegistry.register(token);
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -91,27 +93,27 @@ describe('Progress Token Cross-Platform Translation', () => {
|
|
|
91
93
|
describe('iOS Swift output includes progress current size tokens', () => {
|
|
92
94
|
it('should reference size200 for sm current size', () => {
|
|
93
95
|
expect(iosContent).toContain('nodeSizeSmCurrent');
|
|
94
|
-
expect(iosContent).toMatch(/nodeSizeSmCurrent.*
|
|
96
|
+
expect(iosContent).toMatch(/nodeSizeSmCurrent.*SizingTokens.size200/);
|
|
95
97
|
});
|
|
96
98
|
|
|
97
99
|
it('should reference size250 for md current size', () => {
|
|
98
100
|
expect(iosContent).toContain('nodeSizeMdCurrent');
|
|
99
|
-
expect(iosContent).toMatch(/nodeSizeMdCurrent.*
|
|
101
|
+
expect(iosContent).toMatch(/nodeSizeMdCurrent.*SizingTokens.size250/);
|
|
100
102
|
});
|
|
101
103
|
|
|
102
104
|
it('should reference size300 for lg current size', () => {
|
|
103
105
|
expect(iosContent).toContain('nodeSizeLgCurrent');
|
|
104
|
-
expect(iosContent).toMatch(/nodeSizeLgCurrent.*
|
|
106
|
+
expect(iosContent).toMatch(/nodeSizeLgCurrent.*SizingTokens.size300/);
|
|
105
107
|
});
|
|
106
108
|
|
|
107
|
-
it('should use CGFloat type for
|
|
109
|
+
it('should use CGFloat type for dimensional tokens', () => {
|
|
108
110
|
expect(iosContent).toMatch(/nodeSizeSmCurrent:\s*CGFloat/);
|
|
109
111
|
});
|
|
110
112
|
|
|
111
113
|
it('should reference SizingTokens for base size tokens', () => {
|
|
112
|
-
expect(iosContent).toContain('
|
|
113
|
-
expect(iosContent).toContain('
|
|
114
|
-
expect(iosContent).toContain('
|
|
114
|
+
expect(iosContent).toContain('SizingTokens.size150');
|
|
115
|
+
expect(iosContent).toContain('SizingTokens.size200');
|
|
116
|
+
expect(iosContent).toContain('SizingTokens.size250');
|
|
115
117
|
});
|
|
116
118
|
});
|
|
117
119
|
|
|
@@ -122,23 +124,23 @@ describe('Progress Token Cross-Platform Translation', () => {
|
|
|
122
124
|
describe('Android Kotlin output includes progress current size tokens', () => {
|
|
123
125
|
it('should reference size200 for sm current size', () => {
|
|
124
126
|
expect(androidContent).toContain('nodeSizeSmCurrent');
|
|
125
|
-
expect(androidContent).toMatch(/nodeSizeSmCurrent\s*=\s*
|
|
127
|
+
expect(androidContent).toMatch(/nodeSizeSmCurrent\s*=\s*SizingTokens.size200/);
|
|
126
128
|
});
|
|
127
129
|
|
|
128
130
|
it('should reference size250 for md current size', () => {
|
|
129
131
|
expect(androidContent).toContain('nodeSizeMdCurrent');
|
|
130
|
-
expect(androidContent).toMatch(/nodeSizeMdCurrent\s*=\s*
|
|
132
|
+
expect(androidContent).toMatch(/nodeSizeMdCurrent\s*=\s*SizingTokens.size250/);
|
|
131
133
|
});
|
|
132
134
|
|
|
133
135
|
it('should reference size300 for lg current size', () => {
|
|
134
136
|
expect(androidContent).toContain('nodeSizeLgCurrent');
|
|
135
|
-
expect(androidContent).toMatch(/nodeSizeLgCurrent\s*=\s*
|
|
137
|
+
expect(androidContent).toMatch(/nodeSizeLgCurrent\s*=\s*SizingTokens.size300/);
|
|
136
138
|
});
|
|
137
139
|
|
|
138
140
|
it('should reference SizingTokens for base size tokens', () => {
|
|
139
|
-
expect(androidContent).toContain('
|
|
140
|
-
expect(androidContent).toContain('
|
|
141
|
-
expect(androidContent).toContain('
|
|
141
|
+
expect(androidContent).toContain('SizingTokens.size150');
|
|
142
|
+
expect(androidContent).toContain('SizingTokens.size200');
|
|
143
|
+
expect(androidContent).toContain('SizingTokens.size250');
|
|
142
144
|
});
|
|
143
145
|
});
|
|
144
146
|
|
|
@@ -149,9 +151,9 @@ describe('Progress Token Cross-Platform Translation', () => {
|
|
|
149
151
|
describe('Cross-platform value consistency', () => {
|
|
150
152
|
it('should reference same sizing primitives for current sizes across all platforms', () => {
|
|
151
153
|
const currentSizes = [
|
|
152
|
-
{ cssRef: 'size-200', swiftRef: '
|
|
153
|
-
{ cssRef: 'size-250', swiftRef: '
|
|
154
|
-
{ cssRef: 'size-300', swiftRef: '
|
|
154
|
+
{ cssRef: 'size-200', swiftRef: 'SizingTokens.size200', kotlinRef: 'SizingTokens.size200', cssName: 'sm-current', camelName: 'nodeSizeSmCurrent' },
|
|
155
|
+
{ cssRef: 'size-250', swiftRef: 'SizingTokens.size250', kotlinRef: 'SizingTokens.size250', cssName: 'md-current', camelName: 'nodeSizeMdCurrent' },
|
|
156
|
+
{ cssRef: 'size-300', swiftRef: 'SizingTokens.size300', kotlinRef: 'SizingTokens.size300', cssName: 'lg-current', camelName: 'nodeSizeLgCurrent' },
|
|
155
157
|
];
|
|
156
158
|
|
|
157
159
|
for (const { cssRef, swiftRef, kotlinRef, cssName, camelName } of currentSizes) {
|
|
@@ -20,26 +20,45 @@
|
|
|
20
20
|
* @see .kiro/specs/048-progress-family/design.md (Size Variant, Token Usage sections)
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import { defineComponentTokens } from '../../build/tokens';
|
|
23
|
+
import { defineComponentTokens, getTokenContract } from '../../build/tokens';
|
|
24
|
+
import type { RegisteredComponentToken } from '../../registries/ComponentTokenRegistry';
|
|
24
25
|
import { spacingTokens } from '../../tokens/SpacingTokens';
|
|
25
26
|
import { sizingTokens } from '../../tokens/SizingTokens';
|
|
26
27
|
import { borderWidthTokens } from '../../tokens/BorderWidthTokens';
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* ONE CALL PER FAMILY.
|
|
31
|
+
*
|
|
32
|
+
* Every token registered by a single defineComponentTokens() call is stamped with that
|
|
33
|
+
* call's `family`, and the family drives platform output — notably the primitive class
|
|
34
|
+
* name emitted for reference-path tokens (TokenFileGenerator.getFamilyClassName) and the
|
|
35
|
+
* Android `.dp` suffix. These 10 tokens span THREE primitive families, so they require
|
|
36
|
+
* three calls. A single `family: 'spacing'` call previously produced
|
|
37
|
+
* `SpacingTokens.size150` / `SpacingTokens.borderWidth100` — members no generated platform
|
|
38
|
+
* file defines — the same defect fixed for Button-Icon in PR #126.
|
|
39
|
+
*
|
|
40
|
+
* The three branded results MUST NOT be spread/merged into one registration object: the
|
|
41
|
+
* rich metadata rides on a non-enumerable brand (src/build/tokens/defineComponentTokens.ts,
|
|
42
|
+
* TOKEN_CONTRACT_BRAND) that a spread silently drops. The harvest in loadComponentTokens
|
|
43
|
+
* collects each branded export separately. Use {@link progressTokenValues} for flat
|
|
44
|
+
* value lookups and {@link getProgressRegisteredTokens} for the rich metadata.
|
|
45
|
+
*
|
|
46
|
+
* All three calls declare `component: 'Progress'`, so platform output is still a single
|
|
47
|
+
* `ProgressTokens` Swift enum / Kotlin object.
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Node dimension tokens — reference sizing primitives (dimensions, not spacing).
|
|
52
|
+
*
|
|
32
53
|
* - node.size.{sm|md|lg} — base node dimensions
|
|
33
54
|
* - node.size.{sm|md|lg}.current — emphasized node dimensions (+4px)
|
|
34
|
-
* - node.gap.{sm|md|lg} — spacing between nodes
|
|
35
|
-
* - connector.thickness — connector line width
|
|
36
55
|
*/
|
|
37
|
-
export const
|
|
56
|
+
export const ProgressSizingTokens = defineComponentTokens({
|
|
38
57
|
component: 'Progress',
|
|
39
|
-
family: '
|
|
58
|
+
family: 'sizing',
|
|
40
59
|
tokens: {
|
|
41
60
|
// ========================================================================
|
|
42
|
-
// BASE NODE SIZES
|
|
61
|
+
// BASE NODE SIZES
|
|
43
62
|
// ========================================================================
|
|
44
63
|
|
|
45
64
|
'node.size.sm': {
|
|
@@ -56,7 +75,7 @@ export const ProgressTokens = defineComponentTokens({
|
|
|
56
75
|
},
|
|
57
76
|
|
|
58
77
|
// ========================================================================
|
|
59
|
-
// CURRENT NODE SIZES —
|
|
78
|
+
// CURRENT NODE SIZES — +4px emphasis
|
|
60
79
|
// Provides non-color visual differentiation of active position
|
|
61
80
|
// ========================================================================
|
|
62
81
|
|
|
@@ -72,11 +91,18 @@ export const ProgressTokens = defineComponentTokens({
|
|
|
72
91
|
reference: sizingTokens.size300,
|
|
73
92
|
reasoning: 'Current node emphasis for lg (24px). +4px over base 20px for non-color visual differentiation.',
|
|
74
93
|
},
|
|
94
|
+
},
|
|
95
|
+
});
|
|
75
96
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Node gap tokens — reference spacing primitives (gaps are spacing, not sizing).
|
|
99
|
+
*
|
|
100
|
+
* - node.gap.{sm|md|lg} — spacing between nodes
|
|
101
|
+
*/
|
|
102
|
+
export const ProgressSpacingTokens = defineComponentTokens({
|
|
103
|
+
component: 'Progress',
|
|
104
|
+
family: 'spacing',
|
|
105
|
+
tokens: {
|
|
80
106
|
'node.gap.sm': {
|
|
81
107
|
reference: spacingTokens.space075,
|
|
82
108
|
reasoning: 'Small gap between nodes (6px = 0.75× base). Tight spacing for compact pagination dots in mobile contexts.',
|
|
@@ -89,11 +115,18 @@ export const ProgressTokens = defineComponentTokens({
|
|
|
89
115
|
reference: spacingTokens.space150,
|
|
90
116
|
reasoning: 'Large gap between nodes (12px = 1.5× base). Generous spacing for detailed steppers with labels in desktop contexts.',
|
|
91
117
|
},
|
|
118
|
+
},
|
|
119
|
+
});
|
|
92
120
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Connector tokens — line connecting nodes in steppers. References a borderWidth primitive.
|
|
123
|
+
*
|
|
124
|
+
* - connector.thickness — connector line width
|
|
125
|
+
*/
|
|
126
|
+
export const ProgressBorderWidthTokens = defineComponentTokens({
|
|
127
|
+
component: 'Progress',
|
|
128
|
+
family: 'borderWidth',
|
|
129
|
+
tokens: {
|
|
97
130
|
'connector.thickness': {
|
|
98
131
|
reference: borderWidthTokens.borderWidth100,
|
|
99
132
|
reasoning: 'Connector line thickness (1px). References borderDefault primitive for consistent border treatment across the design system.',
|
|
@@ -101,6 +134,35 @@ export const ProgressTokens = defineComponentTokens({
|
|
|
101
134
|
},
|
|
102
135
|
});
|
|
103
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Flat value map across all three Progress token calls — a READ-ONLY convenience for
|
|
139
|
+
* value lookups (`progressTokenValues['node.size.md']`).
|
|
140
|
+
*
|
|
141
|
+
* NOT a registration surface: spreading drops the non-enumerable brand, so this object
|
|
142
|
+
* deliberately harvests to zero and cannot double-register. For the rich metadata use
|
|
143
|
+
* {@link getProgressRegisteredTokens}, never `getTokenContract(progressTokenValues)`.
|
|
144
|
+
*/
|
|
145
|
+
export const progressTokenValues = {
|
|
146
|
+
...ProgressSizingTokens,
|
|
147
|
+
...ProgressSpacingTokens,
|
|
148
|
+
...ProgressBorderWidthTokens,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* All Progress component tokens with their rich metadata, concatenated across the three
|
|
153
|
+
* family calls in declaration order (sizing → spacing → borderWidth).
|
|
154
|
+
*
|
|
155
|
+
* This is the brand-safe replacement for `getTokenContract(ProgressTokens)`, which is no
|
|
156
|
+
* longer meaningful now that Progress registers through three calls.
|
|
157
|
+
*/
|
|
158
|
+
export function getProgressRegisteredTokens(): RegisteredComponentToken[] {
|
|
159
|
+
return [
|
|
160
|
+
...(getTokenContract(ProgressSizingTokens) ?? []),
|
|
161
|
+
...(getTokenContract(ProgressSpacingTokens) ?? []),
|
|
162
|
+
...(getTokenContract(ProgressBorderWidthTokens) ?? []),
|
|
163
|
+
];
|
|
164
|
+
}
|
|
165
|
+
|
|
104
166
|
// ============================================================================
|
|
105
167
|
// Constants and Utilities
|
|
106
168
|
// ============================================================================
|
|
@@ -135,19 +197,19 @@ export const progressComponentTokenNames = [
|
|
|
135
197
|
* Validate that the progress component token count matches the expected count (13)
|
|
136
198
|
*/
|
|
137
199
|
export function validateProgressComponentTokenCount(): boolean {
|
|
138
|
-
return Object.keys(
|
|
200
|
+
return Object.keys(progressTokenValues).length === PROGRESS_COMPONENT_TOKEN_COUNT;
|
|
139
201
|
}
|
|
140
202
|
|
|
141
203
|
/**
|
|
142
204
|
* Get a single progress component token value by key
|
|
143
205
|
*/
|
|
144
206
|
export function getProgressComponentToken(key: string): number | undefined {
|
|
145
|
-
return (
|
|
207
|
+
return (progressTokenValues as Record<string, number>)[key];
|
|
146
208
|
}
|
|
147
209
|
|
|
148
210
|
/**
|
|
149
211
|
* Get all progress component token entries as key-value pairs
|
|
150
212
|
*/
|
|
151
213
|
export function getAllProgressComponentTokens(): Array<{ name: string; value: number }> {
|
|
152
|
-
return Object.entries(
|
|
214
|
+
return Object.entries(progressTokenValues).map(([name, value]) => ({ name, value }));
|
|
153
215
|
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* - blendHoverLighter: Hover feedback on dark backgrounds (8% lighter)
|
|
17
17
|
* - blendPressedDarker: Pressed state feedback with darkening (12% darker)
|
|
18
18
|
* - blendFocusSaturate: Focus state with increased saturation (8% more saturated)
|
|
19
|
-
* - blendDisabledDesaturate:
|
|
19
|
+
* - blendDisabledDesaturate: DEPRECATED 2026-07-15 — DesignerPunk has no disabled states
|
|
20
20
|
* - blendContainerHoverDarker: Subtle container hover feedback (4% darker)
|
|
21
21
|
* - color.icon.opticalBalance: Icon optical weight compensation (8% lighter)
|
|
22
22
|
*
|
|
@@ -49,6 +49,15 @@ export interface SemanticBlendToken {
|
|
|
49
49
|
|
|
50
50
|
/** Detailed description of semantic meaning and appropriate usage */
|
|
51
51
|
description: string;
|
|
52
|
+
|
|
53
|
+
/** Token is deprecated — do not use in new work; flows to DTCG $extensions.designerpunk.deprecated */
|
|
54
|
+
deprecated?: boolean;
|
|
55
|
+
|
|
56
|
+
/** ISO date the deprecation took effect */
|
|
57
|
+
deprecatedSince?: string;
|
|
58
|
+
|
|
59
|
+
/** Why the token was deprecated and what to do instead */
|
|
60
|
+
deprecatedReason?: string;
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
/**
|
|
@@ -111,6 +120,14 @@ export const blendTokens: Record<string, SemanticBlendToken> = {
|
|
|
111
120
|
description: 'Blend for focus states with saturation increase (8% more saturated) - creates energized, attention-drawing appearance for focused interactive elements'
|
|
112
121
|
},
|
|
113
122
|
|
|
123
|
+
/**
|
|
124
|
+
* @deprecated 2026-07-15 — DesignerPunk does not support disabled states
|
|
125
|
+
* (Button-CTA disabled-state adjudication, ruled REMOVE; the no-disabled-states
|
|
126
|
+
* philosophy holds corpus-wide). If an action is unavailable, do not render the
|
|
127
|
+
* component. Retained for backward compatibility; scheduled for removal in the
|
|
128
|
+
* next major version of @3fn/core. For non-disabled desaturation needs, use the
|
|
129
|
+
* generic desaturate utilities with primitive blend tokens.
|
|
130
|
+
*/
|
|
114
131
|
'blend.disabledDesaturate': {
|
|
115
132
|
name: 'blend.disabledDesaturate',
|
|
116
133
|
primitiveReferences: {
|
|
@@ -118,8 +135,11 @@ export const blendTokens: Record<string, SemanticBlendToken> = {
|
|
|
118
135
|
},
|
|
119
136
|
direction: BlendDirection.DESATURATE,
|
|
120
137
|
category: 'interaction',
|
|
121
|
-
context: '
|
|
122
|
-
description: '
|
|
138
|
+
context: 'DEPRECATED - disabled states are not supported in DesignerPunk',
|
|
139
|
+
description: 'DEPRECATED (2026-07-15): DesignerPunk does not support disabled states — if an action is unavailable, do not render the component. Formerly: blend for disabled states with desaturation (12% less saturated). Scheduled for removal in the next major version.',
|
|
140
|
+
deprecated: true,
|
|
141
|
+
deprecatedSince: '2026-07-15',
|
|
142
|
+
deprecatedReason: 'No-disabled-states philosophy holds corpus-wide (Button-CTA adjudication, 2026-07-15). Unavailable actions should not be rendered; state_loading covers in-flight async actions.'
|
|
123
143
|
},
|
|
124
144
|
|
|
125
145
|
'blend.containerHoverDarker': {
|
|
@@ -200,8 +220,9 @@ export function validateBlendTokenCount(): boolean {
|
|
|
200
220
|
* → Creates vibrant, attention-drawing appearance for focused elements
|
|
201
221
|
*
|
|
202
222
|
* 5. Disabled states?
|
|
203
|
-
* →
|
|
204
|
-
*
|
|
223
|
+
* → DO NOT style disabled states. DesignerPunk does not support disabled states —
|
|
224
|
+
* if an action is unavailable, do not render the component (adjudicated 2026-07-15).
|
|
225
|
+
* → blend.disabledDesaturate is DEPRECATED and scheduled for removal at the next major.
|
|
205
226
|
*
|
|
206
227
|
* 6. Large container/surface hover?
|
|
207
228
|
* → Use blend.containerHoverDarker (4% darker)
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
* the design system while maintaining semantic meaning.
|
|
7
7
|
*
|
|
8
8
|
* Opacity values:
|
|
9
|
-
* - subtle:
|
|
10
|
-
* - medium:
|
|
11
|
-
* - heavy:
|
|
12
|
-
* - ghost:
|
|
9
|
+
* - subtle: opacity088 (88%) - Minimal transparency for subtle effects
|
|
10
|
+
* - medium: opacity072 (72%) - Moderate transparency for overlays
|
|
11
|
+
* - heavy: opacity048 (48%) - Strong transparency for backgrounds
|
|
12
|
+
* - ghost: opacity032 (32%) - Maximum transparency for ghost effects
|
|
13
13
|
*
|
|
14
14
|
* All opacity tokens reference primitive opacity values that can be applied
|
|
15
15
|
* to any color or surface for consistent transparency effects.
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
* }
|
|
66
66
|
* ```
|
|
67
67
|
*
|
|
68
|
-
* @see {@link https://github.com/3fn/
|
|
68
|
+
* @see {@link https://github.com/3fn/DesignerPunk/blob/main/.kiro/specs/011-inset-token-renaming/design.md | Inset Token Renaming Design}
|
|
69
69
|
*/
|
|
70
70
|
export type InsetPadding =
|
|
71
71
|
| 'inset050'
|
|
@@ -294,9 +294,10 @@ export const TOKEN_CATEGORIES = {
|
|
|
294
294
|
'border.default', 'border.strong',
|
|
295
295
|
'radius.100', 'radius.150', 'radius.200',
|
|
296
296
|
],
|
|
297
|
+
// blend.disabledDesaturate removed 2026-07-15: deprecated (no-disabled-states
|
|
298
|
+
// philosophy) — the validator must not suggest it for new component work
|
|
297
299
|
blend: [
|
|
298
|
-
'blend.hoverDarker', 'blend.pressedDarker',
|
|
299
|
-
'blend.disabledDesaturate', 'blend.iconLighter',
|
|
300
|
+
'blend.hoverDarker', 'blend.pressedDarker', 'blend.iconLighter',
|
|
300
301
|
],
|
|
301
302
|
};
|
|
302
303
|
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
tokens:
|
|
2
|
+
progress.connector.thickness:
|
|
3
|
+
component: Progress
|
|
4
|
+
primitiveReferences:
|
|
5
|
+
value: borderWidth100
|
|
6
|
+
platforms:
|
|
7
|
+
web: '--progress-connector-thickness'
|
|
8
|
+
ios: ProgressTokens.connectorThickness
|
|
9
|
+
android: ProgressTokens.connectorThickness
|
|
2
10
|
progress.node.size.sm:
|
|
3
11
|
component: Progress
|
|
4
12
|
primitiveReferences:
|
|
@@ -71,14 +79,6 @@ tokens:
|
|
|
71
79
|
web: '--progress-node-gap-lg'
|
|
72
80
|
ios: ProgressTokens.nodeGapLg
|
|
73
81
|
android: ProgressTokens.nodeGapLg
|
|
74
|
-
progress.connector.thickness:
|
|
75
|
-
component: Progress
|
|
76
|
-
primitiveReferences:
|
|
77
|
-
value: borderWidth100
|
|
78
|
-
platforms:
|
|
79
|
-
web: '--progress-connector-thickness'
|
|
80
|
-
ios: ProgressTokens.connectorThickness
|
|
81
|
-
android: ProgressTokens.connectorThickness
|
|
82
82
|
avatar.size.xs:
|
|
83
83
|
component: Avatar
|
|
84
84
|
primitiveReferences:
|
|
@@ -1418,8 +1418,7 @@ tokens:
|
|
|
1418
1418
|
web: '--blend-disabled-desaturate'
|
|
1419
1419
|
ios: blendDisabledDesaturate
|
|
1420
1420
|
android: blend_disabled_desaturate
|
|
1421
|
-
consumers:
|
|
1422
|
-
- Button-CTA
|
|
1421
|
+
consumers: []
|
|
1423
1422
|
blend.containerHoverDarker:
|
|
1424
1423
|
category: interaction
|
|
1425
1424
|
primitiveReferences:
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @category evergreen
|
|
3
|
-
* @purpose Verify ChangeClassifier maps changes to correct priority tiers
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { ChangeClassifier } from '../pipeline/ChangeClassifier';
|
|
7
|
-
import { ExtractedChange } from '../types';
|
|
8
|
-
|
|
9
|
-
describe('ChangeClassifier', () => {
|
|
10
|
-
let classifier: ChangeClassifier;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
classifier = new ChangeClassifier();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const makeChange = (overrides: Partial<ExtractedChange> = {}): ExtractedChange => ({
|
|
17
|
-
specName: '065-test',
|
|
18
|
-
taskTitle: 'Test task',
|
|
19
|
-
taskType: 'Implementation',
|
|
20
|
-
whatWasDone: 'Did something',
|
|
21
|
-
whyItMatters: 'It matters',
|
|
22
|
-
keyChanges: ['change 1'],
|
|
23
|
-
impact: ['impact 1'],
|
|
24
|
-
...overrides,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
describe('structured deliverables path', () => {
|
|
28
|
-
it('should use deliverable priority directly', () => {
|
|
29
|
-
const change = makeChange({
|
|
30
|
-
deliverables: [{ priority: '🔴', type: 'Component', description: 'New ButtonCTA' }],
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const results = classifier.classify([change]);
|
|
34
|
-
|
|
35
|
-
expect(results[0].priority).toBe('breaking');
|
|
36
|
-
expect(results[0].deliverableType).toBe('Component');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should use highest priority when multiple deliverables', () => {
|
|
40
|
-
const change = makeChange({
|
|
41
|
-
deliverables: [
|
|
42
|
-
{ priority: '🔵', type: 'Governance', description: 'Process update' },
|
|
43
|
-
{ priority: '🔴', type: 'Token', description: 'New color token' },
|
|
44
|
-
{ priority: '🟡', type: 'Tool', description: 'Build change' },
|
|
45
|
-
],
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const results = classifier.classify([change]);
|
|
49
|
-
|
|
50
|
-
expect(results[0].priority).toBe('breaking');
|
|
51
|
-
expect(results[0].deliverableType).toBe('Token');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should map all three emoji priorities', () => {
|
|
55
|
-
const changes = [
|
|
56
|
-
makeChange({ deliverables: [{ priority: '🔴', type: 'Token', description: 'x' }] }),
|
|
57
|
-
makeChange({ deliverables: [{ priority: '🟡', type: 'Tool', description: 'x' }] }),
|
|
58
|
-
makeChange({ deliverables: [{ priority: '🔵', type: 'Governance', description: 'x' }] }),
|
|
59
|
-
];
|
|
60
|
-
|
|
61
|
-
const results = classifier.classify(changes);
|
|
62
|
-
|
|
63
|
-
expect(results[0].priority).toBe('breaking');
|
|
64
|
-
expect(results[1].priority).toBe('prominent');
|
|
65
|
-
expect(results[2].priority).toBe('context');
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe('keyword heuristics fallback', () => {
|
|
70
|
-
it('should classify token changes as breaking', () => {
|
|
71
|
-
const change = makeChange({ taskTitle: 'Add new color token' });
|
|
72
|
-
const results = classifier.classify([change]);
|
|
73
|
-
expect(results[0].priority).toBe('breaking');
|
|
74
|
-
expect(results[0].deliverableType).toBe('Token');
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should classify component changes as breaking', () => {
|
|
78
|
-
const change = makeChange({ whatWasDone: 'Created new component scaffold' });
|
|
79
|
-
const results = classifier.classify([change]);
|
|
80
|
-
expect(results[0].priority).toBe('breaking');
|
|
81
|
-
expect(results[0].deliverableType).toBe('Component');
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should classify tool changes as prominent', () => {
|
|
85
|
-
const change = makeChange({ taskTitle: 'Build tool improvements' });
|
|
86
|
-
const results = classifier.classify([change]);
|
|
87
|
-
expect(results[0].priority).toBe('prominent');
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('should classify governance changes as context', () => {
|
|
91
|
-
const change = makeChange({ keyChanges: ['Updated governance documentation'] });
|
|
92
|
-
const results = classifier.classify([change]);
|
|
93
|
-
expect(results[0].priority).toBe('context');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('should default to context when no keywords match', () => {
|
|
97
|
-
const change = makeChange({ taskTitle: 'Miscellaneous cleanup', whatWasDone: 'Cleaned up files', keyChanges: ['removed old stuff'] });
|
|
98
|
-
const results = classifier.classify([change]);
|
|
99
|
-
expect(results[0].priority).toBe('context');
|
|
100
|
-
expect(results[0].deliverableType).toBe('Other');
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe('sorting', () => {
|
|
105
|
-
it('should sort by priority: breaking > prominent > context', () => {
|
|
106
|
-
const changes = [
|
|
107
|
-
makeChange({ taskTitle: 'Governance update', deliverables: [{ priority: '🔵', type: 'Governance', description: 'x' }] }),
|
|
108
|
-
makeChange({ taskTitle: 'New token', deliverables: [{ priority: '🔴', type: 'Token', description: 'x' }] }),
|
|
109
|
-
makeChange({ taskTitle: 'New tool', deliverables: [{ priority: '🟡', type: 'Tool', description: 'x' }] }),
|
|
110
|
-
];
|
|
111
|
-
|
|
112
|
-
const results = classifier.classify(changes);
|
|
113
|
-
|
|
114
|
-
expect(results[0].priority).toBe('breaking');
|
|
115
|
-
expect(results[1].priority).toBe('prominent');
|
|
116
|
-
expect(results[2].priority).toBe('context');
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
describe('mixed structured and heuristic', () => {
|
|
121
|
-
it('should handle mix of deliverable and no-deliverable changes', () => {
|
|
122
|
-
const changes = [
|
|
123
|
-
makeChange({ taskTitle: 'Misc cleanup', whatWasDone: 'Cleaned things', keyChanges: ['stuff'] }),
|
|
124
|
-
makeChange({ deliverables: [{ priority: '🔴', type: 'Component', description: 'New component' }] }),
|
|
125
|
-
];
|
|
126
|
-
|
|
127
|
-
const results = classifier.classify(changes);
|
|
128
|
-
|
|
129
|
-
expect(results[0].priority).toBe('breaking');
|
|
130
|
-
expect(results[1].priority).toBe('context');
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
});
|