@3fn/core 13.0.0 → 14.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 +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 +5 -5
- package/.kiro/steering/DesignerPunk-Systems-Overview.md +6 -6
- 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 +14 -3
- package/application-mcp-server/src/index.ts +26 -0
- package/dist/ComponentTokens.android.kt +1 -1
- package/dist/ComponentTokens.ios.swift +1 -1
- package/dist/ComponentTokens.web.css +1 -1
- 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 +22 -81
- package/dist/browser/designerpunk.esm.min.js +29 -32
- package/dist/browser/designerpunk.umd.js +22 -81
- package/dist/browser/designerpunk.umd.min.js +42 -45
- package/dist/browser/tokens.css +1 -1
- 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/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/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/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/Component-Development-Guide.md +22 -12
- package/governance/Component-Development-Standards.md +2 -2
- package/governance/Component-Family-Avatar.md +0 -1
- package/governance/Component-Family-Badge.md +0 -1
- package/governance/Component-Family-Button.md +4 -17
- package/governance/Component-Family-Chip.md +0 -1
- package/governance/Component-Family-Container.md +0 -1
- package/governance/Component-Family-Data-Display.md +1 -2
- package/governance/Component-Family-Divider.md +1 -2
- package/governance/Component-Family-Form-Inputs.md +5 -5
- package/governance/Component-Family-Icon.md +1 -2
- package/governance/Component-Family-Loading.md +1 -2
- package/governance/Component-Family-Modal.md +1 -2
- package/governance/Component-Family-Navigation.md +0 -1
- package/governance/Component-Family-Progress.md +0 -1
- package/governance/Component-Inheritance-Structures.md +195 -76
- 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 +54 -38
- package/governance/Component-Templates.md +32 -36
- package/governance/Contract-System-Reference.md +6 -6
- 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 +24 -24
- package/governance/Process-Hook-Operations.md +19 -7
- package/governance/Process-Orchestration-Model-Selection.md +92 -0
- package/governance/Process-Spec-Planning.md +91 -39
- package/governance/Process-Task-Type-Definitions.md +80 -4
- package/governance/Product-Handoff-Protocol.md +2 -0
- package/governance/Rosetta-System-Architecture.md +6 -6
- 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 +21 -21
- 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 +368 -0
- package/governance/completion-documentation-guide.md +11 -8
- 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 +1 -1
- package/governance/release-management-system.md +2 -2
- 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 +23 -21
- 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/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/contracts.yaml +11 -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/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/__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/semantic/BlendTokens.ts +26 -5
- package/src/tokens/semantic/OpacityTokens.ts +4 -4
- package/src/tools/release/__tests__/ReleasePipeline.test.ts +1 -1
- 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/semantics.yaml +1 -2
|
@@ -28,9 +28,7 @@
|
|
|
28
28
|
* | concept query | must include | expected tier |
|
|
29
29
|
* |------------------------|----------------------------------------|---------------|
|
|
30
30
|
* | "RTL" | Web-Authoring-Standards.md | strong |
|
|
31
|
-
* | | Component-Family-Form-Inputs.md | strong |
|
|
32
31
|
* | "internationalization" | Web-Authoring-Standards.md | strong |
|
|
33
|
-
* | | Component-Family-Form-Inputs.md | strong |
|
|
34
32
|
* | "spec planning" | Process-Spec-Planning.md | strong |
|
|
35
33
|
* | "EARS" | Process-Spec-Planning.md | strong |
|
|
36
34
|
* | incidental-token case | only incidental match | partial |
|
|
@@ -60,7 +58,6 @@ const STEERING_DIR = path.resolve(__dirname, '../../../../governance');
|
|
|
60
58
|
* absolute-path prefixes do not make the fixture brittle to CWD differences).
|
|
61
59
|
*/
|
|
62
60
|
const RTL_DOC_A = 'Web-Authoring-Standards.md';
|
|
63
|
-
const RTL_DOC_B = 'Component-Family-Form-Inputs.md';
|
|
64
61
|
const SPEC_PLANNING_DOC = 'Process-Spec-Planning.md';
|
|
65
62
|
|
|
66
63
|
// ---------------------------------------------------------------------------
|
|
@@ -132,7 +129,16 @@ describe('find_docs calibration fixtures — real corpus, tool boundary (Task 4.
|
|
|
132
129
|
// Fixture 1 — RTL / right-to-left
|
|
133
130
|
// -------------------------------------------------------------------------
|
|
134
131
|
|
|
135
|
-
describe('fixture: "RTL" → Web-Authoring-Standards.md
|
|
132
|
+
describe('fixture: "RTL" → Web-Authoring-Standards.md (strong via aliases)', () => {
|
|
133
|
+
/**
|
|
134
|
+
* NOTE (119-B Task 4 alias prune, 2026-08-02): Component-Family-Form-Inputs.md
|
|
135
|
+
* previously carried the same RTL alias set as a second calibration fixture
|
|
136
|
+
* (Spec 121 Task 5). Its only RTL content was two passing bullets, so the
|
|
137
|
+
* aliases were replaced with form-inputs-scoped vocabulary (Lina's domain
|
|
138
|
+
* ruling). The RTL/internationalization recall floor is satisfied by
|
|
139
|
+
* Web-Authoring-Standards.md alone, which has real RTL/logical-properties
|
|
140
|
+
* content and keeps its aliases.
|
|
141
|
+
*/
|
|
136
142
|
let result: FindDocsHandlerResult;
|
|
137
143
|
|
|
138
144
|
beforeAll(() => {
|
|
@@ -155,26 +161,11 @@ describe('find_docs calibration fixtures — real corpus, tool boundary (Task 4.
|
|
|
155
161
|
expect(entry!.matchConfidence).toBe('strong');
|
|
156
162
|
});
|
|
157
163
|
|
|
158
|
-
it('includes Component-Family-Form-Inputs.md', () => {
|
|
159
|
-
const entry = findEntry(result, RTL_DOC_B);
|
|
160
|
-
expect(entry).toBeDefined();
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('classifies Component-Family-Form-Inputs.md as strong (aliases high-signal hit)', () => {
|
|
164
|
-
const entry = findEntry(result, RTL_DOC_B);
|
|
165
|
-
expect(entry!.matchConfidence).toBe('strong');
|
|
166
|
-
});
|
|
167
|
-
|
|
168
164
|
it('emits three distinct Layer fields on Web-Authoring-Standards.md (criterion b)', () => {
|
|
169
165
|
const entry = findEntry(result, RTL_DOC_A);
|
|
170
166
|
assertThreeDistinctLayers(entry!);
|
|
171
167
|
});
|
|
172
168
|
|
|
173
|
-
it('emits three distinct Layer fields on Component-Family-Form-Inputs.md (criterion b)', () => {
|
|
174
|
-
const entry = findEntry(result, RTL_DOC_B);
|
|
175
|
-
assertThreeDistinctLayers(entry!);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
169
|
it('matchedOn for the aliases hit contains "aliases:rtl" (auditable evidence)', () => {
|
|
179
170
|
const entry = findEntry(result, RTL_DOC_A);
|
|
180
171
|
// aliases are high-signal; the token "rtl" must appear in matchedOn as an aliases hit
|
|
@@ -186,7 +177,7 @@ describe('find_docs calibration fixtures — real corpus, tool boundary (Task 4.
|
|
|
186
177
|
// Fixture 2 — internationalization
|
|
187
178
|
// -------------------------------------------------------------------------
|
|
188
179
|
|
|
189
|
-
describe('fixture: "internationalization" →
|
|
180
|
+
describe('fixture: "internationalization" → Web-Authoring-Standards.md (strong)', () => {
|
|
190
181
|
let result: FindDocsHandlerResult;
|
|
191
182
|
|
|
192
183
|
beforeAll(() => {
|
|
@@ -199,12 +190,6 @@ describe('find_docs calibration fixtures — real corpus, tool boundary (Task 4.
|
|
|
199
190
|
expect(entry!.matchConfidence).toBe('strong');
|
|
200
191
|
});
|
|
201
192
|
|
|
202
|
-
it('includes Component-Family-Form-Inputs.md at strong', () => {
|
|
203
|
-
const entry = findEntry(result, RTL_DOC_B);
|
|
204
|
-
expect(entry).toBeDefined();
|
|
205
|
-
expect(entry!.matchConfidence).toBe('strong');
|
|
206
|
-
});
|
|
207
|
-
|
|
208
193
|
it('emits three distinct Layer fields (criterion b)', () => {
|
|
209
194
|
const entry = findEntry(result, RTL_DOC_A);
|
|
210
195
|
assertThreeDistinctLayers(entry!);
|
package/mcp-server/src/relocation-integrity-gate/__tests__/relocation-integrity-gate.test.ts
CHANGED
|
@@ -19,9 +19,12 @@ import {
|
|
|
19
19
|
assertMustFixCouplings,
|
|
20
20
|
assertScope,
|
|
21
21
|
runRelocationIntegrityGate,
|
|
22
|
+
scanPromptReferences,
|
|
22
23
|
LOCKED_IDENTITY_IDS,
|
|
23
24
|
DEFAULT_PROJECT_ROOT,
|
|
25
|
+
DEFAULT_GOVERNANCE_DIR,
|
|
24
26
|
} from '../relocation-integrity-gate';
|
|
27
|
+
import { DocumentIndexer } from '../../indexer/DocumentIndexer';
|
|
25
28
|
|
|
26
29
|
describe('classifyReference — identity vs served vs template (Req 8 AC5)', () => {
|
|
27
30
|
it('classifies a placeholder path-shape as template', () => {
|
|
@@ -198,20 +201,84 @@ describe('runRelocationIntegrityGate — full gate (the 119-A exit check, Req 8
|
|
|
198
201
|
expect(result.unresolved).toEqual([]);
|
|
199
202
|
});
|
|
200
203
|
|
|
201
|
-
it('resolves
|
|
204
|
+
it('resolves a served prompt ref via legacy-fallback — fixture prompt (Req 8 AC1–AC3)', async () => {
|
|
205
|
+
// Anti-vacuity moved OFF live data (2026-07-11, Spec 122 U6): the served floor
|
|
206
|
+
// (≥1 served `.kiro/steering/*.md` ref in the REAL agent prompts) died by progress —
|
|
207
|
+
// the 122 cutovers regenerate agent prompts into runtime-neutral MCP-cue form, removing
|
|
208
|
+
// `.kiro/steering/*.md` file references. With Leonardo (U6) cut over, ZERO live prompts
|
|
209
|
+
// carry served refs (same class as the template floor's death at U3). The served-
|
|
210
|
+
// resolution behavior is now exercised NON-VACUOUSLY against a fixture prompt carrying a
|
|
211
|
+
// real relocated-doc ref, resolved through a real indexer (frozen legacy manifest seeded);
|
|
212
|
+
// the live leg below keeps the every-served-ref-resolves invariant without an inventory floor.
|
|
213
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'rig-served-'));
|
|
214
|
+
const indexer = new DocumentIndexer();
|
|
215
|
+
await indexer.indexDirectory(DEFAULT_GOVERNANCE_DIR); // seeds the frozen legacy manifest at its tail
|
|
216
|
+
try {
|
|
217
|
+
fs.mkdirSync(path.join(root, '.kiro/agents'), { recursive: true });
|
|
218
|
+
fs.writeFileSync(
|
|
219
|
+
path.join(root, '.kiro/agents', 'fixture-prompt.md'),
|
|
220
|
+
'# Fixture\n\nSee `get_section({ path: ".kiro/steering/Token-Governance.md", heading: "Token Usage Governance" })`.\n',
|
|
221
|
+
);
|
|
222
|
+
const scan = scanPromptReferences(root, indexer);
|
|
223
|
+
const served = scan.references.filter((r) => r.role === 'served');
|
|
224
|
+
expect(served.length).toBeGreaterThanOrEqual(1);
|
|
225
|
+
expect(served.every((r) => r.resolved)).toBe(true);
|
|
226
|
+
expect(served.every((r) => r.strategy === 'legacy-fallback')).toBe(true);
|
|
227
|
+
} finally {
|
|
228
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('live prompts: every served ref (if any) resolves via legacy-fallback (Req 8 AC1–AC3)', async () => {
|
|
202
233
|
const result = await runRelocationIntegrityGate();
|
|
203
234
|
const served = result.references.filter((r) => r.role === 'served');
|
|
204
|
-
|
|
235
|
+
// NO count floor: the live corpus legitimately holds zero served refs since U6 (the
|
|
236
|
+
// fixture leg above covers non-vacuous resolution). If any served refs exist, each must
|
|
237
|
+
// resolve via legacy-fallback; the resolutionMechanism description holds regardless.
|
|
205
238
|
expect(served.every((r) => r.resolved)).toBe(true);
|
|
206
239
|
expect(served.every((r) => r.strategy === 'legacy-fallback')).toBe(true);
|
|
207
240
|
expect(result.resolutionMechanism).toMatch(/legacy-fallback/);
|
|
208
241
|
});
|
|
209
242
|
|
|
210
|
-
it('excludes template placeholders from pass/fail (Req 8 AC1 — not real refs)',
|
|
243
|
+
it('excludes template placeholders from pass/fail — fixture prompt (Req 8 AC1 — not real refs)', () => {
|
|
244
|
+
// Anti-vacuity moved OFF live data (2026-07-11, Spec 122 U3): the live floor
|
|
245
|
+
// (≥1 template in the real prompts) died by progress — Ada's U2 regeneration dropped
|
|
246
|
+
// `Token-Family-{Name}.md` (3 → 2) and Lina's U3 regeneration removed the corpus's
|
|
247
|
+
// LAST template placeholders (`Component-Family-{Name}.md` / `{FamilyName}`, 2 → 0),
|
|
248
|
+
// exactly as this test's old comment predicted. The exclusion behavior is now
|
|
249
|
+
// exercised non-vacuously via the extracted reference-axis seam on a fixture prompt;
|
|
250
|
+
// the live leg below keeps the invariant without an inventory floor.
|
|
251
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'rig-tpl-'));
|
|
252
|
+
try {
|
|
253
|
+
fs.mkdirSync(path.join(root, '.kiro/agents'), { recursive: true });
|
|
254
|
+
fs.writeFileSync(
|
|
255
|
+
path.join(root, '.kiro/agents', 'fixture-prompt.md'),
|
|
256
|
+
'# Fixture\n\nSee `get_document_summary({ path: ".kiro/steering/Component-Family-{Name}.md" })`.\n',
|
|
257
|
+
);
|
|
258
|
+
// A template-only scan must never touch the resolver — throwing stub proves it.
|
|
259
|
+
const neverCalled = {
|
|
260
|
+
resolveRef: (): never => {
|
|
261
|
+
throw new Error('resolveRef must not be called for a template placeholder');
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
const scan = scanPromptReferences(root, neverCalled);
|
|
265
|
+
const templates = scan.references.filter((r) => r.role === 'template');
|
|
266
|
+
expect(templates.length).toBe(1);
|
|
267
|
+
expect(templates[0].ref).toBe('.kiro/steering/Component-Family-{Name}.md');
|
|
268
|
+
expect(templates[0].resolved).toBe(false);
|
|
269
|
+
// a template ref must never appear in unresolved — the exclusion under test
|
|
270
|
+
expect(scan.unresolved).toEqual([]);
|
|
271
|
+
} finally {
|
|
272
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('live prompts: any template placeholder stays excluded from unresolved (Req 8 AC1)', async () => {
|
|
211
277
|
const result = await runRelocationIntegrityGate();
|
|
212
278
|
const templates = result.references.filter((r) => r.role === 'template');
|
|
213
|
-
|
|
214
|
-
//
|
|
279
|
+
// NO count floor: the live corpus legitimately holds zero placeholders since U3
|
|
280
|
+
// (see the fixture leg above for the non-vacuous exclusion assertion; the classifier
|
|
281
|
+
// routing itself is directly covered by the classifyReference tests).
|
|
215
282
|
for (const t of templates) {
|
|
216
283
|
expect(result.unresolved.some((u) => u.includes(t.ref))).toBe(false);
|
|
217
284
|
}
|
|
@@ -269,14 +269,44 @@ export function assertMustFixCouplings(projectRoot: string): CouplingCheck[] {
|
|
|
269
269
|
// non-identity .kiro/steering/ doc remains referenced in any agent JSON.
|
|
270
270
|
{
|
|
271
271
|
const dir = path.join(projectRoot, '.kiro/agents');
|
|
272
|
-
const jsons = fs
|
|
272
|
+
const jsons = fs
|
|
273
|
+
.readdirSync(dir)
|
|
274
|
+
.filter((f) => f.endsWith('.json') && !f.endsWith('.attribution.json'))
|
|
275
|
+
.sort();
|
|
276
|
+
|
|
277
|
+
// Spec 122 cutover-ledger awareness (added at Ada's cutover, U2/PR #55): a GENERATED
|
|
278
|
+
// config carries only its designed ambient members — Ada's trim took the fleet total
|
|
279
|
+
// from 122 to 100 governance/ entries and broke the old flat `govEntries >= 120`
|
|
280
|
+
// floor, and every later cutover would break any fixed total again. The floor's real
|
|
281
|
+
// job is anti-vacuity over the HAND-maintained configs (proof the scan actually saw
|
|
282
|
+
// the remediated entries), so it is now PER-CONFIG (≥5 governance/ entries each; the
|
|
283
|
+
// thinnest hand config today carries 9) over NON-ledger configs only. Generated
|
|
284
|
+
// configs are exempt from the floor — their ref integrity is the generator gate's job
|
|
285
|
+
// (122-sweep-1-refs + 122-canonical-vs-truth) — but they stay IN the stray-relocating
|
|
286
|
+
// scan below: no config, hand or generated, may point a relocating doc at
|
|
287
|
+
// .kiro/steering/. When the ledger covers every seat, the floor leg is vacuously true
|
|
288
|
+
// and this gate's remediation duty is fully handed to the generation-era checks.
|
|
289
|
+
let ledgerAgents = new Set<string>();
|
|
290
|
+
try {
|
|
291
|
+
const ledgerText = fs.readFileSync(path.join(projectRoot, 'canonical/cutover-ledger.yaml'), 'utf-8');
|
|
292
|
+
ledgerAgents = new Set([...ledgerText.matchAll(/^\s*-\s*([a-z0-9-]+)\s*$/gm)].map((m) => m[1]));
|
|
293
|
+
} catch {
|
|
294
|
+
ledgerAgents = new Set(); // pre-122 tree: floor applies to all configs, as before
|
|
295
|
+
}
|
|
296
|
+
|
|
273
297
|
let govEntries = 0;
|
|
298
|
+
const thinHandConfigs: string[] = [];
|
|
274
299
|
const strayRelocating = new Set<string>();
|
|
275
300
|
let strayIdentityLeak = false; // an .kiro/steering/ entry that is NOT an identity doc
|
|
276
301
|
for (const j of jsons) {
|
|
277
302
|
const content = fs.readFileSync(path.join(dir, j), 'utf-8');
|
|
303
|
+
const agentName = j.replace(/\.json$/, '');
|
|
278
304
|
const govRe = /(?:file|skill):\/\/[^"]*governance\/[^"]*\.md/g;
|
|
279
|
-
|
|
305
|
+
const configGovEntries = (content.match(govRe) || []).length;
|
|
306
|
+
govEntries += configGovEntries;
|
|
307
|
+
if (!ledgerAgents.has(agentName) && configGovEntries < 5) {
|
|
308
|
+
thinHandConfigs.push(`${j} (${configGovEntries})`);
|
|
309
|
+
}
|
|
280
310
|
const steerRe = /(?:file|skill):\/\/[^"]*\.kiro\/steering\/([^"/]+\.md)/g;
|
|
281
311
|
let mm: RegExpExecArray | null;
|
|
282
312
|
while ((mm = steerRe.exec(content)) !== null) {
|
|
@@ -287,13 +317,13 @@ export function assertMustFixCouplings(projectRoot: string): CouplingCheck[] {
|
|
|
287
317
|
}
|
|
288
318
|
}
|
|
289
319
|
}
|
|
290
|
-
const ok =
|
|
320
|
+
const ok = thinHandConfigs.length === 0 && !strayIdentityLeak;
|
|
291
321
|
checks.push({
|
|
292
322
|
surface: 'agent-definition resources[] (file:// + skill://)',
|
|
293
323
|
remediated: ok,
|
|
294
324
|
detail: ok
|
|
295
|
-
? `governance/ entries=${govEntries} (≥
|
|
296
|
-
: `governance/ entries=${govEntries}; UNREMEDIATED relocating docs still at .kiro/steering/: ${[...strayRelocating].join(', ')}`,
|
|
325
|
+
? `governance/ entries=${govEntries} (per-hand-config floor ≥5 held; ${ledgerAgents.size} generator-governed config(s) exempt); zero relocating docs left at .kiro/steering/`
|
|
326
|
+
: `governance/ entries=${govEntries}; hand configs under the ≥5 floor: ${thinHandConfigs.join(', ') || 'none'}; UNREMEDIATED relocating docs still at .kiro/steering/: ${[...strayRelocating].join(', ')}`,
|
|
297
327
|
});
|
|
298
328
|
}
|
|
299
329
|
|
|
@@ -511,27 +541,28 @@ export interface GateOptions {
|
|
|
511
541
|
indexer?: DocumentIndexer;
|
|
512
542
|
}
|
|
513
543
|
|
|
544
|
+
/** The reference axis's scan output — see {@link scanPromptReferences}. */
|
|
545
|
+
export interface PromptReferenceScan {
|
|
546
|
+
references: ReferenceCheck[];
|
|
547
|
+
unresolved: string[];
|
|
548
|
+
referencedIdentityIds: Set<string>;
|
|
549
|
+
}
|
|
550
|
+
|
|
514
551
|
/**
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
* `
|
|
520
|
-
*
|
|
552
|
+
* The reference axis (Req 8 AC1–AC5), extracted from the orchestrator as its own
|
|
553
|
+
* exported seam: scan every prompt under `projectRoot`, classify each steering ref
|
|
554
|
+
* (template / identity / served), and resolve served refs through the live indexer.
|
|
555
|
+
* Template placeholders are excluded from pass/fail here — they are recorded but
|
|
556
|
+
* NEVER pushed to `unresolved` — which is the behavior the fixture-based unit test
|
|
557
|
+
* exercises directly (the live corpus carries zero placeholders since the Spec 122
|
|
558
|
+
* U3 regeneration, so full-gate runs can no longer test this leg non-vacuously).
|
|
559
|
+
* Only served refs touch the indexer; a template-only or identity-only scan never
|
|
560
|
+
* calls `resolveRef`.
|
|
521
561
|
*/
|
|
522
|
-
export
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
let indexer = opts.indexer;
|
|
527
|
-
if (!indexer) {
|
|
528
|
-
indexer = new DocumentIndexer();
|
|
529
|
-
// indexDirectory seeds the frozen legacy manifest at its tail (re-seed
|
|
530
|
-
// obligation) — so the legacy-fallback resolution mechanism is live here.
|
|
531
|
-
await indexer.indexDirectory(governanceDir);
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// --- Reference axis (Req 8 AC1–AC5) ---
|
|
562
|
+
export function scanPromptReferences(
|
|
563
|
+
projectRoot: string,
|
|
564
|
+
indexer: Pick<DocumentIndexer, 'resolveRef'>
|
|
565
|
+
): PromptReferenceScan {
|
|
535
566
|
const references: ReferenceCheck[] = [];
|
|
536
567
|
const unresolved: string[] = [];
|
|
537
568
|
const referencedIdentityIds = new Set<string>();
|
|
@@ -583,6 +614,32 @@ export async function runRelocationIntegrityGate(opts: GateOptions = {}): Promis
|
|
|
583
614
|
}
|
|
584
615
|
}
|
|
585
616
|
|
|
617
|
+
return { references, unresolved, referencedIdentityIds };
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Run the relocation-integrity gate (the 119-A exit check).
|
|
622
|
+
*
|
|
623
|
+
* Builds a real `DocumentIndexer` over `governance/` (the frozen legacy manifest is
|
|
624
|
+
* seeded automatically at the tail of `indexDirectory`), then exercises the live
|
|
625
|
+
* `resolveRef` per prompt reference. Identity refs bypass MCP (static presence);
|
|
626
|
+
* must-fix couplings + family-guidance + scope are asserted statically.
|
|
627
|
+
*/
|
|
628
|
+
export async function runRelocationIntegrityGate(opts: GateOptions = {}): Promise<GateResult> {
|
|
629
|
+
const projectRoot = opts.projectRoot ?? DEFAULT_PROJECT_ROOT;
|
|
630
|
+
const governanceDir = opts.governanceDir ?? DEFAULT_GOVERNANCE_DIR;
|
|
631
|
+
|
|
632
|
+
let indexer = opts.indexer;
|
|
633
|
+
if (!indexer) {
|
|
634
|
+
indexer = new DocumentIndexer();
|
|
635
|
+
// indexDirectory seeds the frozen legacy manifest at its tail (re-seed
|
|
636
|
+
// obligation) — so the legacy-fallback resolution mechanism is live here.
|
|
637
|
+
await indexer.indexDirectory(governanceDir);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// --- Reference axis (Req 8 AC1–AC5) ---
|
|
641
|
+
const { references, unresolved, referencedIdentityIds } = scanPromptReferences(projectRoot, indexer);
|
|
642
|
+
|
|
586
643
|
// --- Identity axis (Req 8 AC5) ---
|
|
587
644
|
const identity = assertIdentityPresence(projectRoot, referencedIdentityIds);
|
|
588
645
|
for (const c of identity) {
|
|
@@ -16,13 +16,13 @@ import { ErrorHandler, MCPError } from '../utils/error-handler';
|
|
|
16
16
|
*/
|
|
17
17
|
export const listCrossReferencesTool = {
|
|
18
18
|
name: 'list_cross_references',
|
|
19
|
-
description: 'List cross-references in a document. Returns all referenced documents with context, source section, and line number.',
|
|
19
|
+
description: 'List cross-references in a document. Returns all referenced documents with context, source section, and line number. Enumerates both `.md`-path links (target = the linked path, verbatim) and bare-id links validated against the doc-id index (target = the doc id); unresolvable bare-id targets are excluded (surfaced via index-health). Addressing contract (D5): the `path` parameter resolves through the same strategy chain as the other document tools — doc id, then indexed relative path, then legacy `.kiro/steering/…` path.',
|
|
20
20
|
inputSchema: {
|
|
21
21
|
type: 'object' as const,
|
|
22
22
|
properties: {
|
|
23
23
|
path: {
|
|
24
24
|
type: 'string',
|
|
25
|
-
description: 'Document
|
|
25
|
+
description: 'Document ref: doc id (e.g., "token-governance"), indexed relative path, or legacy `.kiro/steering/…` path — same resolver chain as get_document_summary'
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
required: ['path'] as string[]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@3fn/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"description": "True Native cross-platform design system with mathematical foundations",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Peter Michaels Allen",
|
|
@@ -42,42 +42,42 @@
|
|
|
42
42
|
],
|
|
43
43
|
"exports": {
|
|
44
44
|
".": {
|
|
45
|
-
"
|
|
46
|
-
"
|
|
45
|
+
"types": "./dist/browser-entry.d.ts",
|
|
46
|
+
"import": "./dist/browser/designerpunk.esm.js"
|
|
47
47
|
},
|
|
48
48
|
"./components": {
|
|
49
|
-
"
|
|
50
|
-
"
|
|
49
|
+
"types": "./dist/browser-entry.d.ts",
|
|
50
|
+
"import": "./dist/browser/designerpunk.esm.js"
|
|
51
51
|
},
|
|
52
52
|
"./tokens.css": "./dist/DesignTokens.web.css",
|
|
53
53
|
"./component-tokens.css": "./dist/ComponentTokens.web.css",
|
|
54
54
|
"./config": {
|
|
55
|
+
"types": "./dist/config/index.d.ts",
|
|
55
56
|
"import": "./dist/config/index.js",
|
|
56
|
-
"require": "./dist/config/index.js"
|
|
57
|
-
"types": "./dist/config/index.d.ts"
|
|
57
|
+
"require": "./dist/config/index.js"
|
|
58
58
|
},
|
|
59
59
|
"./types": {
|
|
60
|
+
"types": "./dist/types/index.d.ts",
|
|
60
61
|
"import": "./dist/types/index.js",
|
|
61
|
-
"require": "./dist/types/index.js"
|
|
62
|
-
"types": "./dist/types/index.d.ts"
|
|
62
|
+
"require": "./dist/types/index.js"
|
|
63
63
|
},
|
|
64
64
|
"./build": {
|
|
65
|
+
"types": "./dist/build/tokens/index.d.ts",
|
|
65
66
|
"import": "./dist/build/tokens/index.js",
|
|
66
|
-
"require": "./dist/build/tokens/index.js"
|
|
67
|
-
"types": "./dist/build/tokens/index.d.ts"
|
|
67
|
+
"require": "./dist/build/tokens/index.js"
|
|
68
68
|
},
|
|
69
69
|
"./blend": {
|
|
70
|
+
"types": "./dist/blend/index.d.ts",
|
|
70
71
|
"import": "./dist/blend/index.js",
|
|
71
|
-
"require": "./dist/blend/index.js"
|
|
72
|
-
"types": "./dist/blend/index.d.ts"
|
|
72
|
+
"require": "./dist/blend/index.js"
|
|
73
73
|
},
|
|
74
74
|
"./jest-preset": {
|
|
75
75
|
"require": "./dist/testing/jest-preset.js"
|
|
76
76
|
},
|
|
77
77
|
"./testing": {
|
|
78
|
+
"types": "./dist/testing/index.d.ts",
|
|
78
79
|
"import": "./dist/testing/index.js",
|
|
79
|
-
"require": "./dist/testing/index.js"
|
|
80
|
-
"types": "./dist/testing/index.d.ts"
|
|
80
|
+
"require": "./dist/testing/index.js"
|
|
81
81
|
},
|
|
82
82
|
"./grid.css": "./src/styles/responsive-grid.css",
|
|
83
83
|
"./fonts/inter.css": "./src/assets/fonts/inter/inter.css",
|
|
@@ -106,15 +106,15 @@
|
|
|
106
106
|
"build:verify": "node verify-build.js",
|
|
107
107
|
"build:validate": "npx tsx src/validators/buildValidation.ts",
|
|
108
108
|
"lint": "eslint 'src/components/**/*.ts' 'src/components/**/*.tsx' --no-error-on-unmatched-pattern",
|
|
109
|
-
"test": "jest --
|
|
109
|
+
"test": "jest --config jest.functional.config.js",
|
|
110
110
|
"test:all": "jest",
|
|
111
|
+
"test:agent-generator": "jest --config tools/agent-generator/jest.config.js",
|
|
111
112
|
"test:consumer": "jest --roots='<rootDir>/tests' --testMatch='**/consumer-integration.test.ts' --runInBand --testTimeout=120000 --forceExit",
|
|
112
113
|
"test:resolution-matrix": "node src/config/__resolution-matrix__/run-matrix.js",
|
|
113
114
|
"test:performance": "jest --testPathPatterns='performance/__tests__|__tests__/performance'",
|
|
114
115
|
"test:performance:isolated": "jest --config jest.performance.config.js --runInBand",
|
|
115
|
-
"test:
|
|
116
|
-
"test:
|
|
117
|
-
"test:coverage": "jest --coverage --testPathIgnorePatterns='performance/__tests__|__tests__/performance'",
|
|
116
|
+
"test:watch": "jest --watch --config jest.functional.config.js",
|
|
117
|
+
"test:coverage": "jest --coverage --config jest.functional.config.js",
|
|
118
118
|
"release:analyze": "npx tsx src/tools/release/cli/release-tool.ts analyze",
|
|
119
119
|
"release:notes": "npx tsx src/tools/release/cli/release-tool.ts notes",
|
|
120
120
|
"release:run": "npx tsx src/tools/release/cli/release-tool.ts release",
|
|
@@ -122,6 +122,7 @@
|
|
|
122
122
|
"diagnose:release-issues": "node scripts/diagnose-release-issues.js",
|
|
123
123
|
"audit:tokens": "node scripts/audit-component-tokens.js",
|
|
124
124
|
"audit:tokens:detailed": "node scripts/audit-component-tokens.js -- --detailed",
|
|
125
|
+
"audit:coverage-map": "npx tsx tools/agent-generator/coverage-map.ts",
|
|
125
126
|
"audit:mode-parity": "npx tsx src/validators/ModeParity.ts",
|
|
126
127
|
"audit:theme-drift": "npx tsx src/tools/ThemeFileGenerator.ts > /tmp/theme-skeleton-check.ts && diff -u src/tokens/themes/dark/SemanticOverrides.ts /tmp/theme-skeleton-check.ts || echo '⚠️ Theme file drift detected — regenerate with: npm run generate:theme-skeleton'",
|
|
127
128
|
"generate:theme-skeleton": "npx tsx src/tools/ThemeFileGenerator.ts",
|
|
@@ -133,8 +134,9 @@
|
|
|
133
134
|
"check:drift": "node scripts/check-package-name-drift.js",
|
|
134
135
|
"check:id-uniqueness": "tsx scripts/check-id-uniqueness.ts",
|
|
135
136
|
"prepack": "npm run build",
|
|
136
|
-
"
|
|
137
|
-
"
|
|
137
|
+
"verify:token-index-clean": "git diff --quiet token-index/ || (echo '✖ token-index/ is stale relative to the committed state. Regenerate and commit it on the RELEASE BRANCH (it traverses the PR gate with the version bump) before publishing. See .kiro/hooks/RELEASE-FLOW.md.' && exit 1)",
|
|
138
|
+
"prepublishOnly": "npm run build && npm run check:drift && npm run verify:token-index-clean",
|
|
139
|
+
"postpublish": "git diff --quiet token-index/ || echo '⚠️ token-index/ changed during publish — commit it via a PR (main is branch-protected; never push it directly). See .kiro/hooks/RELEASE-FLOW.md.'"
|
|
138
140
|
},
|
|
139
141
|
"devDependencies": {
|
|
140
142
|
"@types/glob": "^8.1.0",
|
|
@@ -183,11 +183,13 @@ describe('CSS Bundling for Browser Distribution', () => {
|
|
|
183
183
|
expect(bundleContent).toMatch(/:hover/);
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
-
it('should contain disabled state styles', () => {
|
|
186
|
+
it('should not contain disabled state styles (no-disabled-states philosophy)', () => {
|
|
187
187
|
const bundleContent = fs.readFileSync(ESM_BUNDLE_PATH, 'utf-8');
|
|
188
|
-
|
|
189
|
-
//
|
|
190
|
-
|
|
188
|
+
|
|
189
|
+
// DesignerPunk does not support disabled states: if an action is
|
|
190
|
+
// unavailable, the component should not be rendered. No component CSS
|
|
191
|
+
// should ship disabled selectors or modifier classes.
|
|
192
|
+
expect(bundleContent).not.toMatch(/:disabled|--disabled/);
|
|
191
193
|
});
|
|
192
194
|
});
|
|
193
195
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "suite": "src/components/core/Avatar-Base/__tests__/Avatar.accessibility.test.ts", "pattern": "^AvatarBaseElement: \"alt\" is required when \"src\" is provided\\.", "reason": "Spec 126 (O2, ratified 2026-07-09) resolved the original Req 5.4 / Req 9.2 tension this entry was seeded against: the warn condition is now `type === 'human' && src && alt == null && !decorative`, so a genuinely decorative or empty-alt (via setAttribute) fixture no longer warns at all. This entry is retained as a safety net, not a live suppression path — every fixture in this suite that legitimately triggers the warn (human + src + absent alt, incl. the property-form alt='' collapse) wraps it in a local jest.spyOn(console,'warn').mockImplementation(() => {}), which per console-fail-setup.ts's documented shadow behavior fully swallows the output before this hook ever sees it. Pattern updated to match the new Spec 126 message string (was: '\"alt\" prop is required when \"src\" is provided')." },
|
|
3
|
+
{ "suite": "src/components/core/Chip-Base/__tests__/ChipBase.test.ts", "pattern": "^ChipBase: Could not calculate blend colors", "reason": "jsdom stylesheet limitation: jsdom never applies real CSS, so the blend-color token lookup cannot succeed and the component's designed CSS-fallback warn fires every run (fired async via rAF). PR #39 adjudicated as environmental noise, not a defect. Component-prefixed pattern (Lina review, PR #39) — a bare 'Could not calculate blend colors' substring is shared by Button components too; prefix-matching prevents accidentally swallowing a cross-component warn. Discharges the pending jsdom-stylesheet-limitation doc-addition (125-B-backlog.md item 5; Thurgood chip, 2026-07-09)." },
|
|
4
|
+
{ "suite": "src/components/core/Chip-Filter/__tests__/ChipFilter.test.ts", "pattern": "^ChipFilter: Could not calculate blend colors", "reason": "jsdom stylesheet limitation: jsdom never applies real CSS, so the blend-color token lookup cannot succeed and the component's designed CSS-fallback warn fires every run (fired async via rAF). PR #39 adjudicated as environmental noise, not a defect. Component-prefixed pattern (Lina review, PR #39) — a bare 'Could not calculate blend colors' substring is shared by Button components too; prefix-matching prevents accidentally swallowing a cross-component warn. Discharges the pending jsdom-stylesheet-limitation doc-addition (125-B-backlog.md item 5; Thurgood chip, 2026-07-09)." },
|
|
5
|
+
{ "suite": "src/components/core/Chip-Input/__tests__/ChipInput.test.ts", "pattern": "^ChipInput: Could not calculate blend colors", "reason": "jsdom stylesheet limitation: jsdom never applies real CSS, so the blend-color token lookup cannot succeed and the component's designed CSS-fallback warn fires every run (fired async via rAF). PR #39 adjudicated as environmental noise, not a defect. Component-prefixed pattern (Lina review, PR #39) — a bare 'Could not calculate blend colors' substring is shared by Button components too; prefix-matching prevents accidentally swallowing a cross-component warn. Discharges the pending jsdom-stylesheet-limitation doc-addition (125-B-backlog.md item 5; Thurgood chip, 2026-07-09)." },
|
|
6
|
+
{ "suite": "src/build/errors/__tests__/ErrorHandler.test.ts", "pattern": "^\\[(ERROR|WARNING|INFO)\\]|^Suggestions:|^ {2}\\u2022 |^ {2}\\.\\.\\. and \\d+ more", "reason": "Deliberate error-path logging: this suite constructs BuildErrors with fake TEST_ERROR/CONFIG_ERROR/BUILD_ERROR codes specifically to assert ErrorHandler's own console-emitting default logger (ErrorHandler.ts defaultLogger/formatErrorMessage) — the console output IS the behavior under test. PR #39 adjudicated as expected noise (96 error blocks silenced fleet-wide, this suite's share among them)." },
|
|
7
|
+
{ "suite": "src/build/errors/__tests__/ErrorHandler.integration.test.ts", "pattern": "^\\[(ERROR|WARNING|INFO)\\]|^Suggestions:|^ {2}\\u2022 |^ {2}\\.\\.\\. and \\d+ more", "reason": "Deliberate error-path logging: this suite exercises ErrorHandler/ErrorReporter integration with fake BUILD_ERROR/CONFIG_ERROR codes — the console output IS the behavior under test. PR #39 adjudicated as expected noise." },
|
|
8
|
+
{ "suite": "product-mcp-server/src/__tests__/GapDetector.test.ts", "pattern": "^\\[mcp-product-server\\] Component directory not found: .* \\u2014 gap detection disabled$", "reason": "Deliberate error-path logging: the 'with missing component directory' tests intentionally point GapDetector at a nonexistent path to assert its disabled-gracefully behavior — the console.error IS the assertion target for the first test and expected repeat noise for the others in the same describe block. PR #39 adjudicated as expected." },
|
|
9
|
+
{ "suite": "product-mcp-server/src/__tests__/ProductIndexerWalk.test.ts", "pattern": "^\\[mcp-product-server\\] Indexed: \\d+ screens, \\d+ domain objects, \\d+ templates, \\d+ one-off components$", "reason": "ProductIndexer.index() logs an informational indexing summary via console.error (not a failure signal) on every index() call. PR #39 adjudicated as expected per-run noise, silenced via a beforeAll spy in this suite." },
|
|
10
|
+
{ "suite": "product-mcp-server/src/__tests__/Spec108-ProductTokens.test.ts", "pattern": "^\\[mcp-product-server\\] Indexed: \\d+ screens, \\d+ domain objects, \\d+ templates, \\d+ one-off components$", "reason": "ProductIndexer.index() logs an informational indexing summary via console.error (not a failure signal) on every index() call. PR #39 adjudicated as expected per-run noise, silenced via a beforeAll spy in this suite." },
|
|
11
|
+
{ "suite": "src/__tests__/integration/Spec107-DesignLanguageContext.test.ts", "pattern": "^\\[mcp-product-server\\] Indexed: \\d+ screens, \\d+ domain objects, \\d+ templates, \\d+ one-off components$", "reason": "ProductIndexer.index() logs an informational indexing summary via console.error (not a failure signal); this suite's ProductIndexer instances are constructed inside nested beforeAll hooks, so PR #39 installed the spy in an outer beforeAll (not beforeEach) to be active before them. Adjudicated as expected noise." },
|
|
12
|
+
{ "suite": "src/cli/__tests__/figma-extract.test.ts", "pattern": "^\\u274c |^Usage: npm run figma:extract|^\\s+npm run figma:extract|^\\s+Run the DTCG generator first|^$", "reason": "Genuinely novel class, adjudicated in this task (125-B Task 4.4, not part of PR #39): figma-extract is a CLI tool whose console.error output IS its product surface — every message this suite asserts on is the deliberate, deterministic error/usage text figma-extract.ts emits (arg validation, DTCG-load failures, extraction failures, usage banners, blank-line separators). This suite installs its own module-top-level console.error spy (mockConsoleError, restored per-file, not per-test) and reads its .mock.calls directly; this hook's beforeEach captures the CURRENT console.error before spying and calls through to it, so the suite's own assertions keep working unaffected." },
|
|
13
|
+
{ "suite": "src/cli/__tests__/figma-push.test.ts", "pattern": "^\\u274c |^Resolution:|^\\s+\\d+\\.\\s|^\\s+-\\s|^\\s+Run the DTCG generator first|^$", "reason": "Genuinely novel class, adjudicated in this task (125-B Task 4.4, not part of PR #39): figma-push is a CLI tool whose console.error output IS its product surface — every message this suite asserts on is the deliberate, deterministic error/resolution text figma-push.ts emits (arg validation, DTCG-load failures, drift/sync-failure reporting with its numbered resolution steps and ' - <detail>' lists, blank-line separators). Same module-top-level console.error spy pattern as figma-extract.test.ts; this hook chains through to it rather than shadowing it." }
|
|
14
|
+
]
|