@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
|
@@ -19238,6 +19238,30 @@ var ComponentMCPServer = class {
|
|
|
19238
19238
|
this.stalenessGate.markIndexed();
|
|
19239
19239
|
await this.server.connect(transport);
|
|
19240
19240
|
console.error(`[${SERVER_NAME}] Server running on stdio`);
|
|
19241
|
+
this.setupShutdownHandlers();
|
|
19242
|
+
}
|
|
19243
|
+
/**
|
|
19244
|
+
* Self-exit on stdin EOF and fatal signals. A stdio MCP server whose parent client
|
|
19245
|
+
* died (or gracefully closed the pipe) has no one to serve, but the file watcher
|
|
19246
|
+
* keeps the event loop alive forever — found live at Spec 122 U3 (~230 orphaned
|
|
19247
|
+
* servers accumulated across harness runs). Exiting on EOF also makes graceful
|
|
19248
|
+
* client closes immediate: the MCP SDK's StdioClientTransport.close() ends stdin
|
|
19249
|
+
* and waits up to 2s for exactly this exit before escalating to SIGTERM.
|
|
19250
|
+
*/
|
|
19251
|
+
setupShutdownHandlers() {
|
|
19252
|
+
let shuttingDown = false;
|
|
19253
|
+
const shutdown = async () => {
|
|
19254
|
+
if (shuttingDown) return;
|
|
19255
|
+
shuttingDown = true;
|
|
19256
|
+
console.error(`[${SERVER_NAME}] Shutting down...`);
|
|
19257
|
+
this.fileWatcher.stop();
|
|
19258
|
+
await this.server.close();
|
|
19259
|
+
process.exit(0);
|
|
19260
|
+
};
|
|
19261
|
+
process.on("SIGINT", shutdown);
|
|
19262
|
+
process.on("SIGTERM", shutdown);
|
|
19263
|
+
process.stdin.on("end", shutdown);
|
|
19264
|
+
process.stdin.on("close", shutdown);
|
|
19241
19265
|
}
|
|
19242
19266
|
registerHandlers() {
|
|
19243
19267
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
|
package/dist/mcp/docs-mcp.js
CHANGED
|
@@ -14341,6 +14341,7 @@ function resolveSection(content, filePath, opts) {
|
|
|
14341
14341
|
}
|
|
14342
14342
|
|
|
14343
14343
|
// mcp-server/src/indexer/cross-ref-parser.ts
|
|
14344
|
+
var BARE_ID_GRAMMAR = /^[a-z0-9][a-z0-9-]*$/;
|
|
14344
14345
|
function extractCrossReferences(content, _filePath) {
|
|
14345
14346
|
const lines = content.split("\n");
|
|
14346
14347
|
const references = [];
|
|
@@ -14363,6 +14364,14 @@ function extractCrossReferences(content, _filePath) {
|
|
|
14363
14364
|
section: currentSection,
|
|
14364
14365
|
lineNumber: i + 1
|
|
14365
14366
|
});
|
|
14367
|
+
} else if (BARE_ID_GRAMMAR.test(target) && !/[/.:#]/.test(target)) {
|
|
14368
|
+
references.push({
|
|
14369
|
+
target,
|
|
14370
|
+
context,
|
|
14371
|
+
section: currentSection,
|
|
14372
|
+
lineNumber: i + 1,
|
|
14373
|
+
kind: "id-candidate"
|
|
14374
|
+
});
|
|
14366
14375
|
}
|
|
14367
14376
|
}
|
|
14368
14377
|
}
|
|
@@ -14380,7 +14389,7 @@ function estimateTokenCount(content) {
|
|
|
14380
14389
|
var fs = __toESM(require("fs"));
|
|
14381
14390
|
var path = __toESM(require("path"));
|
|
14382
14391
|
function determineIndexHealth(options) {
|
|
14383
|
-
const { indexedDocuments, directoryPath, lastIndexTime } = options;
|
|
14392
|
+
const { indexedDocuments, directoryPath, lastIndexTime, crossRefTotals } = options;
|
|
14384
14393
|
const errors = [];
|
|
14385
14394
|
const warnings = [];
|
|
14386
14395
|
const expectedDocs = getExpectedDocuments(directoryPath);
|
|
@@ -14400,7 +14409,15 @@ function determineIndexHealth(options) {
|
|
|
14400
14409
|
if (malformedDocs.length > 0) {
|
|
14401
14410
|
warnings.push(`Malformed metadata: ${malformedDocs.join(", ")}`);
|
|
14402
14411
|
}
|
|
14412
|
+
if (crossRefTotals && crossRefTotals.droppedBareIdCount > 0) {
|
|
14413
|
+
warnings.push(
|
|
14414
|
+
`${crossRefTotals.droppedBareIdCount} unresolved bare-id link targets \u2014 run scan-cross-references.sh for the list`
|
|
14415
|
+
);
|
|
14416
|
+
}
|
|
14403
14417
|
const metrics = calculateIndexMetrics(indexedDocuments);
|
|
14418
|
+
if (crossRefTotals) {
|
|
14419
|
+
metrics.totalCrossReferences = crossRefTotals.validatedCount;
|
|
14420
|
+
}
|
|
14404
14421
|
let status;
|
|
14405
14422
|
if (errors.length > 0) {
|
|
14406
14423
|
status = "failed";
|
|
@@ -14664,6 +14681,25 @@ var DocumentIndexer = class {
|
|
|
14664
14681
|
this.idIndex = /* @__PURE__ */ new Map();
|
|
14665
14682
|
// id → indexedKey
|
|
14666
14683
|
this.legacyPathIndex = /* @__PURE__ */ new Map();
|
|
14684
|
+
// normalizedLegacyPath → indexedKey
|
|
14685
|
+
/**
|
|
14686
|
+
* Validated cross-references per indexed key (Spec 119-B OB-1, Decision 1:
|
|
14687
|
+
* extract-then-validate at INDEX time, one validation point). indexFile
|
|
14688
|
+
* stores the raw parser output (bare-id candidates still tagged); the
|
|
14689
|
+
* post-index validation pass (or reindexFile's inline pass) replaces it with
|
|
14690
|
+
* the validated, TAG-STRIPPED set — the candidate tag never escapes the
|
|
14691
|
+
* indexer. All read surfaces (list_cross_references, getDocumentSummary,
|
|
14692
|
+
* index-health metrics) consume THIS map, never re-extract, so the
|
|
14693
|
+
* crossReferences count is a stable index property.
|
|
14694
|
+
*/
|
|
14695
|
+
this.crossRefsByKey = /* @__PURE__ */ new Map();
|
|
14696
|
+
/**
|
|
14697
|
+
* Bare-id candidates dropped by validation (target not in idIndex) — the
|
|
14698
|
+
* typo-suspicious class. Surfaced on two channels (design Component 6):
|
|
14699
|
+
* scan-cross-references.sh lists individually; index-health emits ONE
|
|
14700
|
+
* aggregate warning when count > 0.
|
|
14701
|
+
*/
|
|
14702
|
+
this.droppedIdCandidates = [];
|
|
14667
14703
|
this.logsDirectory = logsDirectory;
|
|
14668
14704
|
}
|
|
14669
14705
|
/**
|
|
@@ -14682,11 +14718,14 @@ var DocumentIndexer = class {
|
|
|
14682
14718
|
this.documentContent.clear();
|
|
14683
14719
|
this.idIndex.clear();
|
|
14684
14720
|
this.legacyPathIndex.clear();
|
|
14721
|
+
this.crossRefsByKey.clear();
|
|
14722
|
+
this.droppedIdCandidates = [];
|
|
14685
14723
|
const files = this.scanDirectory(directoryPath);
|
|
14686
14724
|
for (const filePath of files) {
|
|
14687
14725
|
await this.indexFile(filePath);
|
|
14688
14726
|
}
|
|
14689
14727
|
this.seedLegacyPaths();
|
|
14728
|
+
this.validateAllCrossReferences();
|
|
14690
14729
|
this.lastIndexTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
14691
14730
|
this.logIndexStateChange("indexing_completed", {
|
|
14692
14731
|
directoryPath,
|
|
@@ -14704,10 +14743,13 @@ var DocumentIndexer = class {
|
|
|
14704
14743
|
this.pruneAddressingEntriesForKey(filePath);
|
|
14705
14744
|
this.documentMap.delete(filePath);
|
|
14706
14745
|
this.documentContent.delete(filePath);
|
|
14746
|
+
this.crossRefsByKey.delete(filePath);
|
|
14747
|
+
this.droppedIdCandidates = this.droppedIdCandidates.filter((d) => d.sourceKey !== filePath);
|
|
14707
14748
|
this.lastIndexTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
14708
14749
|
return;
|
|
14709
14750
|
}
|
|
14710
14751
|
await this.indexFile(filePath);
|
|
14752
|
+
this.validateCrossReferencesForKey(filePath);
|
|
14711
14753
|
this.lastIndexTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
14712
14754
|
}
|
|
14713
14755
|
/**
|
|
@@ -14745,10 +14787,11 @@ var DocumentIndexer = class {
|
|
|
14745
14787
|
* @param filePath - Path to document
|
|
14746
14788
|
*/
|
|
14747
14789
|
getDocumentSummary(filePath) {
|
|
14748
|
-
const
|
|
14790
|
+
const { indexedKey } = this.resolveRef(filePath);
|
|
14791
|
+
const content = this.documentContent.get(indexedKey);
|
|
14749
14792
|
const metadata = extractMetadata(content);
|
|
14750
14793
|
const outline = extractHeadingStructure(content);
|
|
14751
|
-
const crossReferences =
|
|
14794
|
+
const crossReferences = this.crossRefsByKey.get(indexedKey) ?? [];
|
|
14752
14795
|
const crossReferenceInfo = crossReferences.map((ref) => ({
|
|
14753
14796
|
target: ref.target,
|
|
14754
14797
|
context: ref.context,
|
|
@@ -14858,12 +14901,65 @@ ${candidateLines}`
|
|
|
14858
14901
|
/**
|
|
14859
14902
|
* List cross-references in a document
|
|
14860
14903
|
* Returns links without following them
|
|
14861
|
-
*
|
|
14862
|
-
*
|
|
14904
|
+
*
|
|
14905
|
+
* Spec 119-B OB-1: the incoming ref routes through the SAME resolver chain
|
|
14906
|
+
* as every other document-addressed tool (id → indexed key → legacy path,
|
|
14907
|
+
* D5), and the result is the VALIDATED index-time set — `.md` path refs
|
|
14908
|
+
* unchanged, bare-id refs enumerated with target = the doc id; dropped
|
|
14909
|
+
* candidates never appear. Public shape unchanged (no kind tag).
|
|
14910
|
+
*
|
|
14911
|
+
* @param filePath - Document ref: id, indexed relative path, or legacy path
|
|
14863
14912
|
*/
|
|
14864
14913
|
listCrossReferences(filePath) {
|
|
14865
|
-
const
|
|
14866
|
-
return
|
|
14914
|
+
const { indexedKey } = this.resolveRef(filePath);
|
|
14915
|
+
return this.crossRefsByKey.get(indexedKey) ?? [];
|
|
14916
|
+
}
|
|
14917
|
+
/**
|
|
14918
|
+
* Bare-id candidates dropped by validation (Spec 119-B OB-1) — the
|
|
14919
|
+
* typo-suspicious class surfaced via index-health's aggregate warning and
|
|
14920
|
+
* scan-cross-references.sh's individual listing.
|
|
14921
|
+
*/
|
|
14922
|
+
getDroppedIdCandidates() {
|
|
14923
|
+
return this.droppedIdCandidates;
|
|
14924
|
+
}
|
|
14925
|
+
/**
|
|
14926
|
+
* Validate ALL stored cross-reference sets against the completed idIndex
|
|
14927
|
+
* (the post-index hook — Spec 119-B OB-1, Decision 1's single validation
|
|
14928
|
+
* point). Resets the dropped-candidate record.
|
|
14929
|
+
*/
|
|
14930
|
+
validateAllCrossReferences() {
|
|
14931
|
+
this.droppedIdCandidates = [];
|
|
14932
|
+
for (const key of this.crossRefsByKey.keys()) {
|
|
14933
|
+
this.validateCrossReferencesForKey(key);
|
|
14934
|
+
}
|
|
14935
|
+
}
|
|
14936
|
+
/**
|
|
14937
|
+
* Validate one document's stored cross-references against the CURRENT
|
|
14938
|
+
* idIndex. `.md` path refs pass through untouched; bare-id candidates are
|
|
14939
|
+
* kept iff their target is a known doc id (tag stripped — it never escapes
|
|
14940
|
+
* the indexer) and dropped-with-record otherwise.
|
|
14941
|
+
*/
|
|
14942
|
+
validateCrossReferencesForKey(key) {
|
|
14943
|
+
const raw = this.crossRefsByKey.get(key);
|
|
14944
|
+
if (!raw) return;
|
|
14945
|
+
this.droppedIdCandidates = this.droppedIdCandidates.filter((d) => d.sourceKey !== key);
|
|
14946
|
+
const validated = [];
|
|
14947
|
+
for (const ref of raw) {
|
|
14948
|
+
if (ref.kind !== "id-candidate") {
|
|
14949
|
+
validated.push(ref);
|
|
14950
|
+
} else if (this.idIndex.has(ref.target)) {
|
|
14951
|
+
const { kind: _kind, ...publicRef } = ref;
|
|
14952
|
+
validated.push(publicRef);
|
|
14953
|
+
} else {
|
|
14954
|
+
this.droppedIdCandidates.push({
|
|
14955
|
+
sourceKey: key,
|
|
14956
|
+
target: ref.target,
|
|
14957
|
+
section: ref.section,
|
|
14958
|
+
lineNumber: ref.lineNumber
|
|
14959
|
+
});
|
|
14960
|
+
}
|
|
14961
|
+
}
|
|
14962
|
+
this.crossRefsByKey.set(key, validated);
|
|
14867
14963
|
}
|
|
14868
14964
|
/**
|
|
14869
14965
|
* Validate metadata for a document
|
|
@@ -14957,6 +15053,7 @@ ${candidateLines}`
|
|
|
14957
15053
|
viability: frontmatter.viability
|
|
14958
15054
|
};
|
|
14959
15055
|
this.documentMap.set(filePath, documentMetadata);
|
|
15056
|
+
this.crossRefsByKey.set(filePath, extractCrossReferences(content, filePath));
|
|
14960
15057
|
for (const [existingId, existingKey] of this.idIndex) {
|
|
14961
15058
|
if (existingKey === filePath && existingId !== id) this.idIndex.delete(existingId);
|
|
14962
15059
|
}
|
|
@@ -15119,10 +15216,16 @@ ${candidateLines}`
|
|
|
15119
15216
|
this.logIndexStateChange("validation_completed", { status: health2.status, errors: health2.errors });
|
|
15120
15217
|
return health2;
|
|
15121
15218
|
}
|
|
15219
|
+
let validatedCount = 0;
|
|
15220
|
+
for (const refs of this.crossRefsByKey.values()) validatedCount += refs.length;
|
|
15122
15221
|
const health = determineIndexHealth({
|
|
15123
15222
|
indexedDocuments: this.documentContent,
|
|
15124
15223
|
directoryPath: this.directoryPath,
|
|
15125
|
-
lastIndexTime: this.lastIndexTime
|
|
15224
|
+
lastIndexTime: this.lastIndexTime,
|
|
15225
|
+
crossRefTotals: {
|
|
15226
|
+
validatedCount,
|
|
15227
|
+
droppedBareIdCount: this.droppedIdCandidates.length
|
|
15228
|
+
}
|
|
15126
15229
|
});
|
|
15127
15230
|
this.logIndexStateChange("validation_completed", {
|
|
15128
15231
|
status: health.status,
|
|
@@ -16421,13 +16524,13 @@ function formatMcpResponse4(result) {
|
|
|
16421
16524
|
// mcp-server/src/tools/list-cross-references.ts
|
|
16422
16525
|
var listCrossReferencesTool = {
|
|
16423
16526
|
name: "list_cross_references",
|
|
16424
|
-
description: "List cross-references in a document. Returns all referenced documents with context, source section, and line number.",
|
|
16527
|
+
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 \u2014 doc id, then indexed relative path, then legacy `.kiro/steering/\u2026` path.",
|
|
16425
16528
|
inputSchema: {
|
|
16426
16529
|
type: "object",
|
|
16427
16530
|
properties: {
|
|
16428
16531
|
path: {
|
|
16429
16532
|
type: "string",
|
|
16430
|
-
description: 'Document
|
|
16533
|
+
description: 'Document ref: doc id (e.g., "token-governance"), indexed relative path, or legacy `.kiro/steering/\u2026` path \u2014 same resolver chain as get_document_summary'
|
|
16431
16534
|
}
|
|
16432
16535
|
},
|
|
16433
16536
|
required: ["path"]
|
|
@@ -16851,7 +16954,15 @@ var MCPDocumentationServer = class {
|
|
|
16851
16954
|
this.isRunning = false;
|
|
16852
16955
|
}
|
|
16853
16956
|
/**
|
|
16854
|
-
* Set up graceful shutdown handlers
|
|
16957
|
+
* Set up graceful shutdown handlers.
|
|
16958
|
+
*
|
|
16959
|
+
* stdin EOF ('end'/'close') is a first-class shutdown trigger: a stdio MCP server
|
|
16960
|
+
* whose parent client died (or gracefully closed the pipe) has no one to serve, but
|
|
16961
|
+
* the file watcher keeps the event loop alive forever — found live at Spec 122 U3
|
|
16962
|
+
* (~230 orphaned servers accumulated across harness runs, wedging later boots).
|
|
16963
|
+
* Self-exiting on EOF also makes graceful client closes immediate: the MCP SDK's
|
|
16964
|
+
* StdioClientTransport.close() ends stdin and waits up to 2s for exactly this exit
|
|
16965
|
+
* before escalating to SIGTERM.
|
|
16855
16966
|
*/
|
|
16856
16967
|
setupShutdownHandlers() {
|
|
16857
16968
|
const shutdown = async () => {
|
|
@@ -16860,6 +16971,8 @@ var MCPDocumentationServer = class {
|
|
|
16860
16971
|
};
|
|
16861
16972
|
process.on("SIGINT", shutdown);
|
|
16862
16973
|
process.on("SIGTERM", shutdown);
|
|
16974
|
+
process.stdin.on("end", shutdown);
|
|
16975
|
+
process.stdin.on("close", shutdown);
|
|
16863
16976
|
}
|
|
16864
16977
|
};
|
|
16865
16978
|
async function main() {
|
|
@@ -16882,10 +16995,12 @@ async function main() {
|
|
|
16882
16995
|
const server = new MCPDocumentationServer(steeringDir);
|
|
16883
16996
|
await server.start();
|
|
16884
16997
|
}
|
|
16885
|
-
|
|
16886
|
-
|
|
16887
|
-
|
|
16888
|
-
|
|
16998
|
+
if (require.main === module) {
|
|
16999
|
+
main().catch((error2) => {
|
|
17000
|
+
console.error("[MCP Server] Fatal error:", error2);
|
|
17001
|
+
process.exit(1);
|
|
17002
|
+
});
|
|
17003
|
+
}
|
|
16889
17004
|
// Annotate the CommonJS export names for ESM import in node:
|
|
16890
17005
|
0 && (module.exports = {
|
|
16891
17006
|
MCPDocumentationServer,
|
package/dist/mcp/product-mcp.js
CHANGED
|
@@ -24567,6 +24567,31 @@ var ProductMCPServer = class {
|
|
|
24567
24567
|
const transport = new StdioServerTransport();
|
|
24568
24568
|
await this.server.connect(transport);
|
|
24569
24569
|
console.error(`[${SERVER_NAME4}] Server running on stdio`);
|
|
24570
|
+
this.setupShutdownHandlers();
|
|
24571
|
+
}
|
|
24572
|
+
/**
|
|
24573
|
+
* Self-exit on stdin EOF and fatal signals. A stdio MCP server whose parent client
|
|
24574
|
+
* died (or gracefully closed the pipe) has no one to serve, but the file watcher
|
|
24575
|
+
* keeps the event loop alive forever — found live at Spec 122 U3 (~230 orphaned
|
|
24576
|
+
* servers accumulated across harness runs, this server the most-leaked of the
|
|
24577
|
+
* three). Exiting on EOF also makes graceful client closes immediate: the MCP
|
|
24578
|
+
* SDK's StdioClientTransport.close() ends stdin and waits up to 2s for exactly
|
|
24579
|
+
* this exit before escalating to SIGTERM.
|
|
24580
|
+
*/
|
|
24581
|
+
setupShutdownHandlers() {
|
|
24582
|
+
let shuttingDown = false;
|
|
24583
|
+
const shutdown = async () => {
|
|
24584
|
+
if (shuttingDown) return;
|
|
24585
|
+
shuttingDown = true;
|
|
24586
|
+
console.error(`[${SERVER_NAME4}] Shutting down...`);
|
|
24587
|
+
this.fileWatcher?.close();
|
|
24588
|
+
await this.server.close();
|
|
24589
|
+
process.exit(0);
|
|
24590
|
+
};
|
|
24591
|
+
process.on("SIGINT", shutdown);
|
|
24592
|
+
process.on("SIGTERM", shutdown);
|
|
24593
|
+
process.stdin.on("end", shutdown);
|
|
24594
|
+
process.stdin.on("close", shutdown);
|
|
24570
24595
|
}
|
|
24571
24596
|
startFileWatcher() {
|
|
24572
24597
|
if (!fs7.existsSync(this.productDir)) return;
|
|
@@ -108,7 +108,7 @@ exports.opacityTokens = {
|
|
|
108
108
|
category: PrimitiveToken_1.TokenCategory.OPACITY,
|
|
109
109
|
baseValue: exports.OPACITY_BASE_VALUE * 6,
|
|
110
110
|
familyBaseValue: exports.OPACITY_BASE_VALUE,
|
|
111
|
-
description: '
|
|
111
|
+
description: 'Very strong transparency - background scrims and modal overlays (referenced by opacity.heavy)',
|
|
112
112
|
mathematicalRelationship: 'base × 6 = 0.08 × 6 = 0.48',
|
|
113
113
|
baselineGridAlignment: false,
|
|
114
114
|
isStrategicFlexibility: false,
|
|
@@ -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
|
*
|
|
@@ -42,6 +42,12 @@ export interface SemanticBlendToken {
|
|
|
42
42
|
context: string;
|
|
43
43
|
/** Detailed description of semantic meaning and appropriate usage */
|
|
44
44
|
description: string;
|
|
45
|
+
/** Token is deprecated — do not use in new work; flows to DTCG $extensions.designerpunk.deprecated */
|
|
46
|
+
deprecated?: boolean;
|
|
47
|
+
/** ISO date the deprecation took effect */
|
|
48
|
+
deprecatedSince?: string;
|
|
49
|
+
/** Why the token was deprecated and what to do instead */
|
|
50
|
+
deprecatedReason?: string;
|
|
45
51
|
}
|
|
46
52
|
/**
|
|
47
53
|
* Semantic blend tokens for common interaction states
|
|
@@ -87,8 +93,9 @@ export declare function validateBlendTokenCount(): boolean;
|
|
|
87
93
|
* → Creates vibrant, attention-drawing appearance for focused elements
|
|
88
94
|
*
|
|
89
95
|
* 5. Disabled states?
|
|
90
|
-
* →
|
|
91
|
-
*
|
|
96
|
+
* → DO NOT style disabled states. DesignerPunk does not support disabled states —
|
|
97
|
+
* if an action is unavailable, do not render the component (adjudicated 2026-07-15).
|
|
98
|
+
* → blend.disabledDesaturate is DEPRECATED and scheduled for removal at the next major.
|
|
92
99
|
*
|
|
93
100
|
* 6. Large container/surface hover?
|
|
94
101
|
* → Use blend.containerHoverDarker (4% darker)
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* - blendHoverLighter: Hover feedback on dark backgrounds (8% lighter)
|
|
18
18
|
* - blendPressedDarker: Pressed state feedback with darkening (12% darker)
|
|
19
19
|
* - blendFocusSaturate: Focus state with increased saturation (8% more saturated)
|
|
20
|
-
* - blendDisabledDesaturate:
|
|
20
|
+
* - blendDisabledDesaturate: DEPRECATED 2026-07-15 — DesignerPunk has no disabled states
|
|
21
21
|
* - blendContainerHoverDarker: Subtle container hover feedback (4% darker)
|
|
22
22
|
* - color.icon.opticalBalance: Icon optical weight compensation (8% lighter)
|
|
23
23
|
*
|
|
@@ -84,6 +84,14 @@ exports.blendTokens = {
|
|
|
84
84
|
context: 'Focus state feedback - more vibrant, attention-drawing color',
|
|
85
85
|
description: 'Blend for focus states with saturation increase (8% more saturated) - creates energized, attention-drawing appearance for focused interactive elements'
|
|
86
86
|
},
|
|
87
|
+
/**
|
|
88
|
+
* @deprecated 2026-07-15 — DesignerPunk does not support disabled states
|
|
89
|
+
* (Button-CTA disabled-state adjudication, ruled REMOVE; the no-disabled-states
|
|
90
|
+
* philosophy holds corpus-wide). If an action is unavailable, do not render the
|
|
91
|
+
* component. Retained for backward compatibility; scheduled for removal in the
|
|
92
|
+
* next major version of @3fn/core. For non-disabled desaturation needs, use the
|
|
93
|
+
* generic desaturate utilities with primitive blend tokens.
|
|
94
|
+
*/
|
|
87
95
|
'blend.disabledDesaturate': {
|
|
88
96
|
name: 'blend.disabledDesaturate',
|
|
89
97
|
primitiveReferences: {
|
|
@@ -91,8 +99,11 @@ exports.blendTokens = {
|
|
|
91
99
|
},
|
|
92
100
|
direction: BlendTokens_1.BlendDirection.DESATURATE,
|
|
93
101
|
category: 'interaction',
|
|
94
|
-
context: '
|
|
95
|
-
description: '
|
|
102
|
+
context: 'DEPRECATED - disabled states are not supported in DesignerPunk',
|
|
103
|
+
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.',
|
|
104
|
+
deprecated: true,
|
|
105
|
+
deprecatedSince: '2026-07-15',
|
|
106
|
+
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.'
|
|
96
107
|
},
|
|
97
108
|
'blend.containerHoverDarker': {
|
|
98
109
|
name: 'blend.containerHoverDarker',
|
|
@@ -166,8 +177,9 @@ function validateBlendTokenCount() {
|
|
|
166
177
|
* → Creates vibrant, attention-drawing appearance for focused elements
|
|
167
178
|
*
|
|
168
179
|
* 5. Disabled states?
|
|
169
|
-
* →
|
|
170
|
-
*
|
|
180
|
+
* → DO NOT style disabled states. DesignerPunk does not support disabled states —
|
|
181
|
+
* if an action is unavailable, do not render the component (adjudicated 2026-07-15).
|
|
182
|
+
* → blend.disabledDesaturate is DEPRECATED and scheduled for removal at the next major.
|
|
171
183
|
*
|
|
172
184
|
* 6. Large container/surface hover?
|
|
173
185
|
* → 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.
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
* the design system while maintaining semantic meaning.
|
|
8
8
|
*
|
|
9
9
|
* Opacity values:
|
|
10
|
-
* - subtle:
|
|
11
|
-
* - medium:
|
|
12
|
-
* - heavy:
|
|
13
|
-
* - ghost:
|
|
10
|
+
* - subtle: opacity088 (88%) - Minimal transparency for subtle effects
|
|
11
|
+
* - medium: opacity072 (72%) - Moderate transparency for overlays
|
|
12
|
+
* - heavy: opacity048 (48%) - Strong transparency for backgrounds
|
|
13
|
+
* - ghost: opacity032 (32%) - Maximum transparency for ghost effects
|
|
14
14
|
*
|
|
15
15
|
* All opacity tokens reference primitive opacity values that can be applied
|
|
16
16
|
* to any color or surface for consistent transparency effects.
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
* }
|
|
65
65
|
* ```
|
|
66
66
|
*
|
|
67
|
-
* @see {@link https://github.com/3fn/
|
|
67
|
+
* @see {@link https://github.com/3fn/DesignerPunk/blob/main/.kiro/specs/011-inset-token-renaming/design.md | Inset Token Renaming Design}
|
|
68
68
|
*/
|
|
69
69
|
export type InsetPadding = 'inset050' | 'inset100' | 'inset150' | 'inset200' | 'inset300' | 'inset400';
|
|
70
70
|
//# sourceMappingURL=ComponentTypes.d.ts.map
|
|
@@ -208,9 +208,10 @@ exports.TOKEN_CATEGORIES = {
|
|
|
208
208
|
'border.default', 'border.strong',
|
|
209
209
|
'radius.100', 'radius.150', 'radius.200',
|
|
210
210
|
],
|
|
211
|
+
// blend.disabledDesaturate removed 2026-07-15: deprecated (no-disabled-states
|
|
212
|
+
// philosophy) — the validator must not suggest it for new component work
|
|
211
213
|
blend: [
|
|
212
|
-
'blend.hoverDarker', 'blend.pressedDarker',
|
|
213
|
-
'blend.disabledDesaturate', 'blend.iconLighter',
|
|
214
|
+
'blend.hoverDarker', 'blend.pressedDarker', 'blend.iconLighter',
|
|
214
215
|
],
|
|
215
216
|
};
|
|
216
217
|
/**
|
|
@@ -61,7 +61,7 @@ description: Guide for building components with appropriate token usage, True Na
|
|
|
61
61
|
4. ✅ **Icon Integration Anti-Patterns** (what NOT to do)
|
|
62
62
|
5. ✅ **Icon Integration Checklist** (verification steps)
|
|
63
63
|
|
|
64
|
-
**WHEN implementing interaction states (hover, pressed, focus
|
|
64
|
+
**WHEN implementing interaction states (hover, pressed, focus) THEN read:**
|
|
65
65
|
1. ✅ **Blend Utility Integration** (how to use blend utilities for state colors)
|
|
66
66
|
2. ✅ **Semantic Blend Token Reference** (which token/function for each state)
|
|
67
67
|
3. ✅ **Blend Utility Anti-Patterns** (what NOT to do - no opacity, no filters)
|
|
@@ -433,7 +433,8 @@ export interface ButtonCTAProps {
|
|
|
433
433
|
variant?: 'primary' | 'secondary' | 'danger'; // ✅ Use variant
|
|
434
434
|
size?: 'small' | 'medium' | 'large';
|
|
435
435
|
icon?: string;
|
|
436
|
-
disabled
|
|
436
|
+
// No `disabled` prop — DesignerPunk components do not support disabled
|
|
437
|
+
// states (see "No Disabled States" under Behavioral Contracts Workflow).
|
|
437
438
|
}
|
|
438
439
|
```
|
|
439
440
|
|
|
@@ -494,14 +495,27 @@ Author `contracts.yaml` after `types.ts` and before platform implementation. Con
|
|
|
494
495
|
### Naming Convention
|
|
495
496
|
|
|
496
497
|
All contract names follow `{category}_{concept}` in `snake_case`:
|
|
497
|
-
- `interaction_focusable`, `
|
|
498
|
+
- `interaction_focusable`, `state_error`, `accessibility_reduced_motion`
|
|
498
499
|
- 10 categories: accessibility, animation, composition, content, interaction, layout, performance, state, validation, visual
|
|
499
500
|
|
|
501
|
+
### No Disabled States
|
|
502
|
+
|
|
503
|
+
**DesignerPunk components MUST NOT declare a disabled-state contract.** Per the 2026-07-15 adjudication (`.kiro/issues/button-cta-disabled-state-adjudication.md`), the no-disabled-states philosophy holds corpus-wide with zero exceptions. Every component's `contracts.yaml` MUST instead carry the standardized exclusion block:
|
|
504
|
+
|
|
505
|
+
```yaml
|
|
506
|
+
excludes:
|
|
507
|
+
state_disabled:
|
|
508
|
+
reason: "DesignerPunk does not support disabled states for usability and accessibility reasons. If an action is unavailable, the component should not be rendered."
|
|
509
|
+
category: state
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
If an action is temporarily unavailable, use one of these alternatives instead: `state_loading` (in-flight async operation), validate-on-press/validate-on-blur (surface the error rather than disabling the trigger), or don't render the component (no valid path forward). See Component-Templates.md § "No Disabled States — Standardized Exclusion" for the full rationale and reference implementation.
|
|
513
|
+
|
|
500
514
|
### Concept Catalog Consultation
|
|
501
515
|
|
|
502
516
|
Before naming a contract, query the Concept Catalog via MCP:
|
|
503
517
|
```
|
|
504
|
-
get_section({ path: "
|
|
518
|
+
get_section({ path: "contract-system-reference", heading: "Concept Catalog" })
|
|
505
519
|
```
|
|
506
520
|
- Use existing catalog concepts whenever possible
|
|
507
521
|
- If a behavior needs a new concept, propose a catalog addition (ballot measure) before using it
|
|
@@ -517,7 +531,7 @@ get_section({ path: ".kiro/steering/Contract-System-Reference.md", heading: "Con
|
|
|
517
531
|
|
|
518
532
|
For the full contract system (taxonomy, canonical format, classification rules, inheritance patterns):
|
|
519
533
|
```
|
|
520
|
-
get_document_full({ path: "
|
|
534
|
+
get_document_full({ path: "contract-system-reference" })
|
|
521
535
|
```
|
|
522
536
|
|
|
523
537
|
---
|
|
@@ -1036,7 +1050,7 @@ theme.colorActionPrimary
|
|
|
1036
1050
|
|
|
1037
1051
|
### Overview
|
|
1038
1052
|
|
|
1039
|
-
Blend utilities enable components to create new opaque colors for interaction states (hover, pressed, focus
|
|
1053
|
+
Blend utilities enable components to create new opaque colors for interaction states (hover, pressed, focus) rather than using opacity-based workarounds. All components should use blend utilities for state color modifications.
|
|
1040
1054
|
|
|
1041
1055
|
### Why Blend Utilities Over CSS Filters
|
|
1042
1056
|
|
|
@@ -1064,7 +1078,7 @@ Blend utilities enable components to create new opaque colors for interaction st
|
|
|
1064
1078
|
|
|
1065
1079
|
- Importing `getBlendUtilities()` from the theme-aware blend utilities module
|
|
1066
1080
|
- Initializing blend utilities in the constructor
|
|
1067
|
-
- Calculating state colors (hover, pressed,
|
|
1081
|
+
- Calculating state colors (hover, pressed, icon) in `connectedCallback()`
|
|
1068
1082
|
- Applying calculated colors via CSS custom properties
|
|
1069
1083
|
- Retry pattern for handling CSS custom property timing
|
|
1070
1084
|
|
|
@@ -1076,7 +1090,6 @@ Blend utilities enable components to create new opaque colors for interaction st
|
|
|
1076
1090
|
- Hover state colors (darken or lighten based on background)
|
|
1077
1091
|
- Pressed state colors (stronger darkening than hover)
|
|
1078
1092
|
- Focus state colors (increased saturation for emphasis)
|
|
1079
|
-
- Disabled state colors (desaturation for muted appearance)
|
|
1080
1093
|
- Icon optical balance (lightening for visual weight compensation)
|
|
1081
1094
|
|
|
1082
1095
|
### Web Platform Usage
|
|
@@ -1096,7 +1109,6 @@ class MyComponent extends HTMLElement {
|
|
|
1096
1109
|
// Calculate state colors
|
|
1097
1110
|
this._hoverColor = blendUtils.hoverColor(primaryColor); // 8% darker
|
|
1098
1111
|
this._pressedColor = blendUtils.pressedColor(primaryColor); // 12% darker
|
|
1099
|
-
this._disabledColor = blendUtils.disabledColor(primaryColor); // 12% desaturated
|
|
1100
1112
|
this._focusColor = blendUtils.focusColor(primaryColor); // 8% more saturated
|
|
1101
1113
|
}
|
|
1102
1114
|
}
|
|
@@ -1145,7 +1157,6 @@ fun MyComponent(primaryColor: Color) {
|
|
|
1145
1157
|
| Hover (dark bg) | `blend.hoverLighter` | `lighterBlend(color, 0.08)` | 8% lighter |
|
|
1146
1158
|
| Pressed | `blend.pressedDarker` | `pressedColor()` | 12% darker |
|
|
1147
1159
|
| Focus | `blend.focusSaturate` | `focusColor()` | 8% more saturated |
|
|
1148
|
-
| Disabled | `blend.disabledDesaturate` | `disabledColor()` | 12% desaturated |
|
|
1149
1160
|
| Container hover | `blend.containerHoverDarker` | `darkerBlend(color, 0.04)` | 4% darker |
|
|
1150
1161
|
| Icon optical | `color.icon.opticalBalance` | `iconColor()` | 8% lighter |
|
|
1151
1162
|
|
|
@@ -1464,7 +1475,7 @@ All component-scoped CSS custom properties MUST use the `--_[abbrev]-*` naming p
|
|
|
1464
1475
|
| Button-CTA | `_cta` | `--_cta-hover-bg`, `--_cta-pressed-bg` |
|
|
1465
1476
|
| Button-VerticalList-Item | `_vlbi` | `--_vlbi-background`, `--_vlbi-border-color` |
|
|
1466
1477
|
| ButtonIcon | `_bi` | `--_bi-hover-bg`, `--_bi-icon-color` |
|
|
1467
|
-
| Input-Text-Base | `_itb` | `--_itb-focus-color
|
|
1478
|
+
| Input-Text-Base | `_itb` | `--_itb-focus-color` |
|
|
1468
1479
|
|
|
1469
1480
|
### When to Use Each Type
|
|
1470
1481
|
|
|
@@ -1492,7 +1503,6 @@ All component-scoped CSS custom properties MUST use the `--_[abbrev]-*` naming p
|
|
|
1492
1503
|
/* Component-scoped properties - internal, calculated */
|
|
1493
1504
|
--_cta-hover-bg: /* calculated by blend utilities */;
|
|
1494
1505
|
--_cta-pressed-bg: /* calculated by blend utilities */;
|
|
1495
|
-
--_cta-disabled-bg: /* calculated by blend utilities */;
|
|
1496
1506
|
}
|
|
1497
1507
|
|
|
1498
1508
|
.button-cta {
|
|
@@ -13,7 +13,7 @@ description: Step-by-step guidelines for creating new component families in the
|
|
|
13
13
|
**Scope**: cross-project
|
|
14
14
|
**Layer**: 2
|
|
15
15
|
**Relevant Tasks**: component-development, architecture, spec-planning
|
|
16
|
-
**Last Reviewed**: 2026-
|
|
16
|
+
**Last Reviewed**: 2026-07-05
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
@@ -1121,7 +1121,7 @@ test_integration:
|
|
|
1121
1121
|
#### Completion Documentation
|
|
1122
1122
|
|
|
1123
1123
|
1. **Create Summary Document**: `docs/specs/[spec-name]/task-N-summary.md`
|
|
1124
|
-
2. **
|
|
1124
|
+
2. **Open the Task PR**: `./.kiro/hooks/complete-task.sh "Task N Complete: Description (<spec>)"` — complete at merge; release analysis runs post-merge on `main`
|
|
1125
1125
|
|
|
1126
1126
|
#### Version Impact
|
|
1127
1127
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
id: component-family-avatar
|
|
3
3
|
inclusion: manual
|
|
4
4
|
name: Component-Family-Avatar
|
|
5
|
-
aliases: avatar family work
|
|
6
5
|
description: Avatar component family — identity representation with shape-based entity differentiation (circle for humans, hexagon for AI agents), image support with loading states and fallback. Load when working with avatar components, identity representation, or user/agent visual differentiation.
|
|
7
6
|
---
|
|
8
7
|
|