{"_id":"@calibrate-ds/dna","_rev":"16-0838cada9bac34215ecb42ce375ee627","name":"@calibrate-ds/dna","dist-tags":{"latest":"0.2.18"},"versions":{"0.2.1":{"name":"@calibrate-ds/dna","version":"0.2.1","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.1","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"homepage":"https://github.com/thedeepadalja/prompt-to-both/tree/main/packages/dna#readme","bugs":{"url":"https://github.com/thedeepadalja/prompt-to-both/issues"},"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"ab2bf7f4d07ca70de146263051ecb9518f4c7c9d","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.1.tgz","fileCount":30,"integrity":"sha512-vOwawFUi/uAboVKDobzvBCOJYzMu6/bpQUeoSQm2vPXFo+CFO6zosg2cP66C1JOz6J1X2rM48ZPYJGIpbRgLTg==","signatures":[{"sig":"MEQCICL2zGZmQ7q8Dq4Z6EfpH4Z6w/VHc6Wj3Z+4kqB7gvrRAiA5955PLEBQ6XQ21gyyDLdUTLehMxItGiHlF6TDhFZ8Jg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":188507},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"5924a321a7405ae157101c63067263d289798a53","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:identity-staleness && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"repository":{"url":"git+https://github.com/thedeepadalja/prompt-to-both.git","type":"git","directory":"packages/dna"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.1_1786313796503_0.47507153305704986","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@calibrate-ds/dna","version":"0.2.2","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.2","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"f32dd8e92c5e4cb3c3632950ddafc2bdd6fb6929","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.2.tgz","fileCount":30,"integrity":"sha512-7XPwM1jqwPfLfDLvW1bCx1lpsdT2RHa6pjnxvkrswCz9H8zOoc/9z/X6K52/QALcI1qUm9K5xf0BW1t4wQLyHw==","signatures":[{"sig":"MEUCIF2ZqLJCXiH00Xz91ZRQ7xKvYPK31DA6lsQYZkkk/pjGAiEAifqCntpBw90VcC7hX9MtWMpnLt7XEBB1E+qDFog3qmQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":188183},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"6a2965c674f966d8eb58f882354d574fc1b2070d","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:identity-staleness && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.2_1786314316104_0.6828114407512558","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@calibrate-ds/dna","version":"0.2.3","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.3","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"f9fea1c7b66b9209ec12fd5ed39ea033f40357f7","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.3.tgz","fileCount":32,"integrity":"sha512-Xzv6NmsOPAJ74Vzkh7EjN71VwCqnjtrtPIm9a9Y3Zvq8Q6sxbCNG5AouYXMMJm7ctbIFSq+hTv4tIE2hZse7Hw==","signatures":[{"sig":"MEUCIQCWZhCAAYXu2F4tCxk671vG/puQXUvfQp4NtZz+3fTT4wIgehkE/3vm2WhFvJeMDnx94Fqi4J5itHcdgfzjVPPWiU0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":197106},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"220364702f0aff85c451db220270d8b1862aa481","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:identity-staleness && npm run check:ts-capability && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":"^5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.3_1786503355856_0.7023860784488463","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@calibrate-ds/dna","version":"0.2.4","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.4","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"5b3367667a602bba8e347cca8f561332243fef99","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.4.tgz","fileCount":32,"integrity":"sha512-S5XFHG9wMBaqcWcJTck5l6r0fGq+K/JsFoNjrWQOPiCr83n1FUz6+hbnhEpMlWkn7WRQgOucsoukgwWX7S3zOw==","signatures":[{"sig":"MEYCIQDCe2zdMTmi88+7pryd/rr19tnhHXY9oLx9dI2nWqR8mwIhAKpd4/tHegNi7gQl6cjgNVe4DxWUj/Z/g0HA89pZXP93","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":202227},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"bf52dd430e2ba5f71082bae030c2ae4698eeda52","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.4_1786542556279_0.16373040248483894","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"@calibrate-ds/dna","version":"0.2.5","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.5","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"a6f9b3d00614dd5113519d12ed5c5075c1d1b0e8","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.5.tgz","fileCount":32,"integrity":"sha512-SmAxtwFt5dj8YAZFg8drkgvG1UtnseJPt9P8VLRKMFYTEJrjnqbPr5eyOnKnCf2HpGUNllT4vMSx87Q0/JNGag==","signatures":[{"sig":"MEUCIBre4FznA41EU3kx+WWTRB0OtSThMFd0HlRwfZki0SrIAiEA+F+/4X3AGoZQMAxj0EnkFJ9sH2jHCsnnFDMClzq7pwM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":202919},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"4fc7a42d76cef1c3e124a49bb4ddc9b0185e2f8a","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.5_1786555537506_0.4542648479499216","host":"s3://npm-registry-packages-npm-production"}},"0.2.6":{"name":"@calibrate-ds/dna","version":"0.2.6","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.6","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"d314c2880d091a49d702b94dffe180fc73b3b093","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.6.tgz","fileCount":32,"integrity":"sha512-mgrQTnLFUrV9RVj4sRewGaKnp+qd8U1165Aswsd15UusA4Hyn/wkGfoCaCdL64PD7RpSCaI6psiKP27yvVUdPA==","signatures":[{"sig":"MEQCIFM+GX68NTdaxizVUkn6vNTHroVsarcTtoiSxPl9rX9mAiAuld8NXmPTW3//RXWnJ6eGiZyAfgoB++N+7vmL1GAwzw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":216328},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"059aa1c6412f9fd1495484f4208e9597ae92173e","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.6_1786556769613_0.09870080292290795","host":"s3://npm-registry-packages-npm-production"}},"0.2.7":{"name":"@calibrate-ds/dna","version":"0.2.7","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.7","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"9e9f314ce6562ca6ebe9c65bc826215cd800a726","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.7.tgz","fileCount":32,"integrity":"sha512-6S43zWg+f2Oc+5GkqISGfBA+IOiSurcIfX4xFzHhC8yy8+sFeRfLpt6BTd4+Pc4fJaz4YJoF8COgw/PX70TEfQ==","signatures":[{"sig":"MEUCIQCZUZvOuL00xy9KbNa68KwBV9D42EauDyF0q64FEvHI0wIgTPq/1zPGMmM7Vun46DGIHolzVsIvqWcLZISGdKmyPyY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":220422},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"70ef6f3f05cded1d125d4b02a64e73b5b2745785","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.7_1786558443098_0.6627210427548837","host":"s3://npm-registry-packages-npm-production"}},"0.2.8":{"name":"@calibrate-ds/dna","version":"0.2.8","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.8","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"1f85bd7888a5f2f26d2330d1d2acdc266f9c85b9","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.8.tgz","fileCount":32,"integrity":"sha512-x35IwAU3sHD5Xlk25zO+gJx1plO6mvTNPRtrFFsVhg+mG7T33AC09YG34Qjkao8znhI9WSarupogQW1PfseIzw==","signatures":[{"sig":"MEYCIQCQKTka2dbobohb5gA3evvsvDMgTK/FeqKSZsaUd/EyEQIhALTd5AScqf8GlIG8HAo3VgTd4xGAA+Jzjq+HOG2CBsAM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":229642},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"77e9c9ac36ad974fc8a9347dbfc4f24ce9107d63","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:fabrication-class && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:fabrication-class":"node test/fabrication-class.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.8_1786560693784_0.16189266270085523","host":"s3://npm-registry-packages-npm-production"}},"0.2.9":{"name":"@calibrate-ds/dna","version":"0.2.9","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.9","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"033cfb966ef8e3bc95ca2e8cf7d3dd02eb493a9a","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.9.tgz","fileCount":32,"integrity":"sha512-tEQyYKREx2m4A+EA6V1wal7hsAp4MlUl68JAko1F9Pd4T0WW3vVYsJAIq8SgAGewhzMqUvA1mBRHcDoVSk0dag==","signatures":[{"sig":"MEYCIQC2EKuCxivuGXDtlBrBOfp7nHr4GlCoreQHGffgc6wE1gIhAL8hZVIrBPb5Qsbllow2Ahn2UgmODf830HaEgnT1vsWJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":232570},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"43432a1e6db3214c5fc3fbdebebcfcc78b23a626","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:fabrication-class && npm run check:observed-color-fabrication && npm run check:jsts-resolver-fabrication && npm run check:start-check-agreement && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:fabrication-class":"node test/fabrication-class.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-check-agreement":"node test/start-check-agreement.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:jsts-resolver-fabrication":"node test/jsts-resolver-fabrication.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:observed-color-fabrication":"node test/observed-color-fabrication.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.9_1786562839080_0.4769027982102285","host":"s3://npm-registry-packages-npm-production"}},"0.2.12":{"name":"@calibrate-ds/dna","version":"0.2.12","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.12","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"1276ffe88e51a6e2642f08da401ddd7a7c7076c4","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.12.tgz","fileCount":32,"integrity":"sha512-gSVb+fZBiauyf/aWOCGaYi7T8NDlbb3U3lHrY+L3b9WAMrnl68In4OqYW6ZrWnZsoAt1+CB0ZGSsTd21bpe+pw==","signatures":[{"sig":"MEUCIB10G+1exohceb2BQw/8CtC+HQ94U2L1Ty2s2Dp3ZJqNAiEA7GDRtZRriQYy8lGaflyc271VjCEbKGs/4jfA7Aj2f2w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":248404},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"5ae47d37383a36fd6178041499b4baa3507ae962","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:similar-fixtures && npm run check:similar-parse-diagnostics && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:hook-install && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:fabrication-class && npm run check:observed-color-fabrication && npm run check:jsts-resolver-fabrication && npm run check:start-check-agreement && npm run check:jsts-extraction-completeness && npm run check:figma-manifest-fabrication && npm run check:generic","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:hook-install":"node test/hook-install.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:fabrication-class":"node test/fabrication-class.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-check-agreement":"node test/start-check-agreement.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:jsts-resolver-fabrication":"node test/jsts-resolver-fabrication.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:similar-parse-diagnostics":"node test/similar-parse-diagnostics.test.mjs","check:figma-manifest-fabrication":"node test/figma-manifest-fabrication.test.mjs","check:observed-color-fabrication":"node test/observed-color-fabrication.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:jsts-extraction-completeness":"node test/jsts-extraction-completeness.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.12_1786568717769_0.6775279788884752","host":"s3://npm-registry-packages-npm-production"}},"0.2.13":{"name":"@calibrate-ds/dna","version":"0.2.13","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.13","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"c817f3238e39cc89d86262750e0c2f952e8db81c","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.13.tgz","fileCount":32,"integrity":"sha512-p3zBqJwkY00EU9Trm/f4qaNPS7apyP2sROf4/bQopGfF1EA4dA2w87q4eljEShmA2fIEROyvosJGmi1LQUD3ew==","signatures":[{"sig":"MEUCIQD+S7iDYc5v5aakozFPguFFhD2L+6nEZlTEnOjQj/gT8gIgGD9zfBO2tHET2bt/AMXz6pyg05qEs7rZmAL8dOVjzCQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":262460},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"7ed546eaec8ff21053797d048cb1b1d0204a2885","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:css-declared-scale && npm run check:similar-fixtures && npm run check:similar-parse-diagnostics && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:hook-install && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:fabrication-class && npm run check:observed-color-fabrication && npm run check:jsts-resolver-fabrication && npm run check:start-check-agreement && npm run check:jsts-extraction-completeness && npm run check:figma-manifest-fabrication && npm run check:generic && npm run check:prefer-token-class-downgrade","check:mcp":"node test/mcp.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:hook-install":"node test/hook-install.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:fabrication-class":"node test/fabrication-class.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:css-declared-scale":"node test/css-declared-scale.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-check-agreement":"node test/start-check-agreement.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:jsts-resolver-fabrication":"node test/jsts-resolver-fabrication.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:similar-parse-diagnostics":"node test/similar-parse-diagnostics.test.mjs","check:figma-manifest-fabrication":"node test/figma-manifest-fabrication.test.mjs","check:observed-color-fabrication":"node test/observed-color-fabrication.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:jsts-extraction-completeness":"node test/jsts-extraction-completeness.test.mjs","check:prefer-token-class-downgrade":"node test/prefer-token-class-downgrade.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.13_1786573733325_0.23506460168403787","host":"s3://npm-registry-packages-npm-production"}},"0.2.14":{"name":"@calibrate-ds/dna","version":"0.2.14","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.14","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"f5f8e61cae34244d5f898925289e2f8319f07b2b","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.14.tgz","fileCount":33,"integrity":"sha512-1LcZUx8l9G/MJhi8xZPdm/sdJh/hKEtDHTeWvNwz4m4UW+INrIRyjX/FoYPo72gpnkm0MIcFzayytjJhvdI7dA==","signatures":[{"sig":"MEQCIELLUBfQOQI+ziKWvkqDrveixnmWbph9aXcR2E47P15fAiB4WZMMNBVDHG8sZh3Z09WJ9FQLbcL3ZytrD2DEBF2KIA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":319715},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"505928ae2f7b1267178428a830218998f4e00111","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:css-declared-scale && npm run check:spacing-scale-extraction && npm run check:radius-modeling && npm run check:allow && npm run check:similar-fixtures && npm run check:similar-parse-diagnostics && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:hook-install && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:fabrication-class && npm run check:observed-color-fabrication && npm run check:jsts-resolver-fabrication && npm run check:start-check-agreement && npm run check:jsts-extraction-completeness && npm run check:figma-manifest-fabrication && npm run check:generic && npm run check:prefer-token-class-downgrade && npm run check:ghost-tokens-observed-fabrication","check:mcp":"node test/mcp.test.mjs","check:allow":"node test/allow.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:hook-install":"node test/hook-install.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:radius-modeling":"node test/radius-modeling.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:fabrication-class":"node test/fabrication-class.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:css-declared-scale":"node test/css-declared-scale.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-check-agreement":"node test/start-check-agreement.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:spacing-scale-extraction":"node test/spacing-scale-extraction.test.mjs","check:jsts-resolver-fabrication":"node test/jsts-resolver-fabrication.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:similar-parse-diagnostics":"node test/similar-parse-diagnostics.test.mjs","check:figma-manifest-fabrication":"node test/figma-manifest-fabrication.test.mjs","check:observed-color-fabrication":"node test/observed-color-fabrication.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:jsts-extraction-completeness":"node test/jsts-extraction-completeness.test.mjs","check:prefer-token-class-downgrade":"node test/prefer-token-class-downgrade.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs","check:ghost-tokens-observed-fabrication":"node test/ghost-tokens-observed-fabrication.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.14_1786594250333_0.3209899937619598","host":"s3://npm-registry-packages-npm-production"}},"0.2.15":{"name":"@calibrate-ds/dna","version":"0.2.15","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.15","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"b868d257af7e1e3836e5a74e649d1e3ee13fb601","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.15.tgz","fileCount":33,"integrity":"sha512-YzrvDAjx7wi5kJsr4GkvK4LS56LDoSsMI+dqGSSCIkx8FI8vQLlTE40E3yjwOwuTJ06B9Jb737Wpw17jx82wTg==","signatures":[{"sig":"MEQCIGqU7bQfP9MEgLoZayLu3GYw7ALtdj+T1WIU+mPy8ulQAiBWAMTyizGjDIPzIzn5iggMbAa6XMygUTxdSWUnrN8jxw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":348659},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"94549e1388e21b3f18fc7821b1b2522bd677f64f","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:css-declared-scale && npm run check:spacing-scale-extraction && npm run check:radius-modeling && npm run check:allow && npm run check:similar-fixtures && npm run check:similar-parse-diagnostics && npm run check:similar-clone-detection && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:hook-install && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:fabrication-class && npm run check:observed-color-fabrication && npm run check:jsts-resolver-fabrication && npm run check:start-check-agreement && npm run check:jsts-extraction-completeness && npm run check:figma-manifest-fabrication && npm run check:generic && npm run check:prefer-token-class-downgrade && npm run check:ghost-tokens-observed-fabrication && npm run check:length-token-classification","check:mcp":"node test/mcp.test.mjs","check:allow":"node test/allow.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:hook-install":"node test/hook-install.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:radius-modeling":"node test/radius-modeling.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:fabrication-class":"node test/fabrication-class.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:css-declared-scale":"node test/css-declared-scale.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-check-agreement":"node test/start-check-agreement.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:similar-clone-detection":"node test/similar-clone-detection.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:spacing-scale-extraction":"node test/spacing-scale-extraction.test.mjs","check:jsts-resolver-fabrication":"node test/jsts-resolver-fabrication.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:similar-parse-diagnostics":"node test/similar-parse-diagnostics.test.mjs","check:figma-manifest-fabrication":"node test/figma-manifest-fabrication.test.mjs","check:observed-color-fabrication":"node test/observed-color-fabrication.test.mjs","check:length-token-classification":"node test/length-token-classification.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:jsts-extraction-completeness":"node test/jsts-extraction-completeness.test.mjs","check:prefer-token-class-downgrade":"node test/prefer-token-class-downgrade.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs","check:ghost-tokens-observed-fabrication":"node test/ghost-tokens-observed-fabrication.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.15_1786733542121_0.5850644495556823","host":"s3://npm-registry-packages-npm-production"}},"0.2.16":{"name":"@calibrate-ds/dna","version":"0.2.16","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.16","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"5ebf987fd91658414b9f9696eb83b9085481d914","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.16.tgz","fileCount":37,"integrity":"sha512-8c4LWMGVbwKUC18EzmU05BEhyYprLMMM8bk0c4v4qUGZLWOXMQamMPZvILrfWEgqkhCpvvsCNPdbewwe0bMubQ==","signatures":[{"sig":"MEQCIDDwlWaXrS+Fz4NybUcrglOqdxZfWa3sRV2AEp1r27afAiAfj9J7Jw+JdkCDa3X3wKyV93dG7Q5W+x3YOfJMszr9+w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":391227},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"74664c60fafd00ae151a2b713cd9fd1b0d91705e","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:css-declared-scale && npm run check:spacing-scale-extraction && npm run check:radius-modeling && npm run check:allow && npm run check:similar-fixtures && npm run check:similar-parse-diagnostics && npm run check:similar-clone-detection && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:hook-install && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:fabrication-class && npm run check:observed-color-fabrication && npm run check:jsts-resolver-fabrication && npm run check:start-check-agreement && npm run check:jsts-extraction-completeness && npm run check:figma-manifest-fabrication && npm run check:figma-dump-schema && npm run check:figma-diff && npm run check:generic && npm run check:prefer-token-class-downgrade && npm run check:ghost-tokens-observed-fabrication && npm run check:length-token-classification && npm run check:resolve && npm run check:mcp-resolve","check:mcp":"node test/mcp.test.mjs","check:allow":"node test/allow.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:resolve":"node test/resolve.test.mjs","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:figma-diff":"node test/figma-diff.test.mjs","check:mcp-resolve":"node test/mcp-resolve.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:hook-install":"node test/hook-install.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:radius-modeling":"node test/radius-modeling.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:fabrication-class":"node test/fabrication-class.test.mjs","check:figma-dump-schema":"node test/figma-dump-schema.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:css-declared-scale":"node test/css-declared-scale.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-check-agreement":"node test/start-check-agreement.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:similar-clone-detection":"node test/similar-clone-detection.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:spacing-scale-extraction":"node test/spacing-scale-extraction.test.mjs","check:jsts-resolver-fabrication":"node test/jsts-resolver-fabrication.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:similar-parse-diagnostics":"node test/similar-parse-diagnostics.test.mjs","check:figma-manifest-fabrication":"node test/figma-manifest-fabrication.test.mjs","check:observed-color-fabrication":"node test/observed-color-fabrication.test.mjs","check:length-token-classification":"node test/length-token-classification.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:jsts-extraction-completeness":"node test/jsts-extraction-completeness.test.mjs","check:prefer-token-class-downgrade":"node test/prefer-token-class-downgrade.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs","check:ghost-tokens-observed-fabrication":"node test/ghost-tokens-observed-fabrication.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.16_1786999399372_0.7952196878201603","host":"s3://npm-registry-packages-npm-production"}},"0.2.17":{"name":"@calibrate-ds/dna","version":"0.2.17","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","_id":"@calibrate-ds/dna@0.2.17","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"ec5a83580f00e089c487699f9c23abd4a5a255cc","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.17.tgz","fileCount":37,"integrity":"sha512-cW4SGZjWCOi0TORrDXKBWnP0KXzCzzd9MYLBqajkXzCCCjH7ZYdLnHHHNyYTGpbXpLA0cKRhQpEo1HUlFJqJ+Q==","signatures":[{"sig":"MEQCIDvl/QujjEBCK/J3Iv1ttT9y3jw7A34AeesYINXOAgwtAiAIyqDXqeuwCQV1PS9gIYi62aFwHM8MofRfAcQ0DYwb6w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":401782},"main":"index.mjs","type":"module","engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"7d23e81439dd60b6d98c6979252f390f9bc91b77","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:css-declared-scale && npm run check:spacing-scale-extraction && npm run check:radius-modeling && npm run check:allow && npm run check:similar-fixtures && npm run check:similar-parse-diagnostics && npm run check:similar-clone-detection && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:rendered-spawn-failure && npm run check:agent-instructions && npm run check:gitignore && npm run check:hook-install && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:fabrication-class && npm run check:observed-color-fabrication && npm run check:jsts-resolver-fabrication && npm run check:start-check-agreement && npm run check:jsts-extraction-completeness && npm run check:figma-manifest-fabrication && npm run check:figma-dump-schema && npm run check:figma-diff && npm run check:generic && npm run check:prefer-token-class-downgrade && npm run check:ghost-tokens-observed-fabrication && npm run check:length-token-classification && npm run check:resolve && npm run check:mcp-resolve && npm run check:hsl-channel-tokens","check:mcp":"node test/mcp.test.mjs","check:allow":"node test/allow.test.mjs","check:tiers":"node test/tiers.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:resolve":"node test/resolve.test.mjs","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:figma-diff":"node test/figma-diff.test.mjs","check:mcp-resolve":"node test/mcp-resolve.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:hook-install":"node test/hook-install.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:radius-modeling":"node test/radius-modeling.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:fabrication-class":"node test/fabrication-class.test.mjs","check:figma-dump-schema":"node test/figma-dump-schema.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:css-declared-scale":"node test/css-declared-scale.test.mjs","check:hsl-channel-tokens":"node test/hsl-channel-tokens.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-check-agreement":"node test/start-check-agreement.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:similar-clone-detection":"node test/similar-clone-detection.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:spacing-scale-extraction":"node test/spacing-scale-extraction.test.mjs","check:jsts-resolver-fabrication":"node test/jsts-resolver-fabrication.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:similar-parse-diagnostics":"node test/similar-parse-diagnostics.test.mjs","check:figma-manifest-fabrication":"node test/figma-manifest-fabrication.test.mjs","check:observed-color-fabrication":"node test/observed-color-fabrication.test.mjs","check:length-token-classification":"node test/length-token-classification.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:jsts-extraction-completeness":"node test/jsts-extraction-completeness.test.mjs","check:prefer-token-class-downgrade":"node test/prefer-token-class-downgrade.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs","check:ghost-tokens-observed-fabrication":"node test/ghost-tokens-observed-fabrication.test.mjs"},"_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dna_0.2.17_1787085212522_0.2974002267491842","host":"s3://npm-registry-packages-npm-production"}},"0.2.18":{"_id":"@calibrate-ds/dna@0.2.18","bin":{"dna":"bin/dna.mjs"},"dist":{"shasum":"073cb741cf9ae347e47e7422f356520846f48fa7","tarball":"https://registry.npmjs.org/@calibrate-ds/dna/-/dna-0.2.18.tgz","fileCount":41,"integrity":"sha512-8YW4dbuJiOiJE5ysNZUQatjKdrxK0GGJQUOYtG+R5AB4iQKdIs/egWpjgbgXGMfMCHEJSCLLFHKCdu5LZbHyMQ==","signatures":[{"sig":"MEQCICIVlrJX6+wnzlgo4eorDKnnaWwAgwt/wVR/HTWz3QA+AiBWSRtdGVq8DBuWV5DSUHvEMN3yzmPGaUDR90e5QJayaw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAvBoJ6AJ/Nzd3iIfjrQsUY0jdthcNtlcggPtnUzKiiBAiEApJ48qJAhmg7u8d3i/MyPyxxHOykXD7QcHZTZigyuRRk="}],"unpackedSize":783296},"main":"index.mjs","name":"@calibrate-ds/dna","type":"module","author":{"name":"DeepReidy","email":"deep@reidy.ai"},"engines":{"node":">=18.17"},"exports":{".":"./index.mjs"},"gitHead":"d64792fa5264251e86f15cadfa8836a7ae89b452","license":"FSL-1.1-MIT","scripts":{"test":"npm run check:tristate && npm run check:inventory-recursive && npm run check:inventory-descriptions && npm run check:tiers && npm run check:first-run && npm run check:start-inventory-dirs && npm run check:start-inventory-dirs-backfill && npm run check:tailwind-only && npm run check:color-family-shadeless && npm run check:shorthand-color-props && npm run check:box-shadow-multi-shadow && npm run check:off-grid-spacing-negative && npm run check:off-grid-spacing-scale-mode && npm run check:off-grid-spacing-identity-scale && npm run check:css-declared-scale && npm run check:spacing-scale-extraction && npm run check:radius-modeling && npm run check:allow && npm run check:similar-fixtures && npm run check:similar-parse-diagnostics && npm run check:similar-clone-detection && npm run check:similar-conditional-children && npm run check:similar-min-coverage && npm run check:mcp && npm run check:mcp-similar && npm run check:mcp-start-preview && npm run check:mcp-check-optional && npm run check:mcp-check-steps && npm run check:rendered-spawn-failure && npm run check:rendered-per-route && npm run check:rendered-color-undeclared && npm run check:rendered-teardown-pids && npm run check:rendered-foreign-server && npm run check:rendered-routes-shape && npm run check:agent-instructions && npm run check:gitignore && npm run check:hook-install && npm run check:agent-block && npm run check:identity-staleness && npm run check:ts-capability && npm run check:skipped-resolver-report && npm run check:mcp-check-skipped && npm run check:coverage-accounting && npm run check:start-unreadable-file && npm run check:base-ref-validation && npm run check:fabrication-class && npm run check:observed-color-fabrication && npm run check:jsts-resolver-fabrication && npm run check:start-check-agreement && npm run check:jsts-extraction-completeness && npm run check:figma-manifest-fabrication && npm run check:figma-dump-schema && npm run check:figma-diff && npm run check:generic && npm run check:prefer-token-class-downgrade && npm run check:ghost-tokens-observed-fabrication && npm run check:length-token-classification && npm run check:resolve && npm run check:mcp-resolve && npm run check:hsl-channel-tokens && npm run check:modern-color-functions && npm run check:source-text-hygiene && npm run check:render-probe-color-form && npm run check:last-audit-summary && npm run check:seed-dead-rules && npm run check:force-preserves-provenance && npm run check:force-preserves-annotations && npm run check:doctor && npm run check:doctor-config && npm run check:builtin-type-size && npm run check:drift-warnings && npm run check:block-ignore && npm run check:ledger-malformed-line && npm run check:cn-load-failure && npm run check:rules-merge && npm run check:cli-config-flag","check:mcp":"node test/mcp.test.mjs","check:allow":"node test/allow.test.mjs","check:tiers":"node test/tiers.test.mjs","check:doctor":"node test/doctor.test.mjs","check:generic":"node scripts/check-generic.mjs --audit","check:resolve":"node test/resolve.test.mjs","check:tristate":"node test/tristate.test.mjs","prepublishOnly":"node scripts/license-gate.mjs && npm test","check:first-run":"node test/first-run.test.mjs","check:gitignore":"node test/gitignore.test.mjs","check:figma-diff":"node test/figma-diff.test.mjs","check:agent-block":"node test/agent-block.test.mjs","check:mcp-resolve":"node test/mcp-resolve.test.mjs","check:mcp-similar":"node test/mcp-similar.test.mjs","check:rules-merge":"node test/rules-merge.test.mjs","check:block-ignore":"node test/block-ignore.test.mjs","check:hook-install":"node test/hook-install.test.mjs","check:doctor-config":"node test/check-config.test.mjs","check:tailwind-only":"node test/tailwind-only.test.mjs","check:ts-capability":"node test/ts-capability.test.mjs","check:drift-warnings":"node test/drift-warnings.test.mjs","check:cli-config-flag":"node test/cli-config-flag.test.mjs","check:cn-load-failure":"node test/check-cn-load-failure.test.mjs","check:mcp-check-steps":"node test/mcp-check-steps.test.mjs","check:radius-modeling":"node test/radius-modeling.test.mjs","check:seed-dead-rules":"node test/seed-dead-rules.test.mjs","check:similar-fixtures":"node test/similar.test.mjs","check:builtin-type-size":"node test/builtin-type-size.test.mjs","check:fabrication-class":"node test/fabrication-class.test.mjs","check:figma-dump-schema":"node test/figma-dump-schema.test.mjs","check:mcp-check-skipped":"node test/mcp-check-skipped.test.mjs","check:mcp-start-preview":"node test/mcp-start-preview.test.mjs","check:agent-instructions":"node test/agent-instructions.test.mjs","check:css-declared-scale":"node test/css-declared-scale.test.mjs","check:hsl-channel-tokens":"node test/hsl-channel-tokens.test.mjs","check:identity-staleness":"node test/identity-staleness.test.mjs","check:last-audit-summary":"node test/last-audit-summary.test.mjs","check:mcp-check-optional":"node test/mcp-check-optional.test.mjs","check:rendered-per-route":"node test/rendered-per-route.test.mjs","check:base-ref-validation":"node test/base-ref-validation.test.mjs","check:coverage-accounting":"node test/coverage-accounting.test.mjs","check:inventory-recursive":"node test/inventory-recursive.test.mjs","check:source-text-hygiene":"node test/source-text-hygiene.test.mjs","check:similar-min-coverage":"node test/similar-min-coverage.test.mjs","check:start-inventory-dirs":"node test/start-inventory-dirs.test.mjs","check:ledger-malformed-line":"node test/ledger-malformed-line.test.mjs","check:rendered-routes-shape":"node test/rendered-routes-shape.test.mjs","check:shorthand-color-props":"node test/shorthand-color-props.test.mjs","check:start-check-agreement":"node test/start-check-agreement.test.mjs","check:start-unreadable-file":"node test/start-unreadable-file.test.mjs","check:color-family-shadeless":"node test/color-family-shadeless.test.mjs","check:inventory-descriptions":"node test/inventory-descriptions.test.mjs","check:modern-color-functions":"node test/modern-color-functions.test.mjs","check:rendered-spawn-failure":"node test/rendered-spawn-failure.test.mjs","check:rendered-teardown-pids":"node test/rendered-teardown-pids.test.mjs","check:box-shadow-multi-shadow":"node test/box-shadow-multi-shadow.test.mjs","check:render-probe-color-form":"node test/render-probe-color-form.test.mjs","check:rendered-foreign-server":"node test/rendered-foreign-server.test.mjs","check:similar-clone-detection":"node test/similar-clone-detection.test.mjs","check:skipped-resolver-report":"node test/skipped-resolver-report.test.mjs","check:spacing-scale-extraction":"node test/spacing-scale-extraction.test.mjs","check:jsts-resolver-fabrication":"node test/jsts-resolver-fabrication.test.mjs","check:off-grid-spacing-negative":"node test/off-grid-spacing-negative.test.mjs","check:rendered-color-undeclared":"node test/rendered-color-undeclared.test.mjs","check:similar-parse-diagnostics":"node test/similar-parse-diagnostics.test.mjs","check:figma-manifest-fabrication":"node test/figma-manifest-fabrication.test.mjs","check:force-preserves-provenance":"node test/force-preserves-provenance.test.mjs","check:observed-color-fabrication":"node test/observed-color-fabrication.test.mjs","check:force-preserves-annotations":"node test/force-preserves-annotations.test.mjs","check:length-token-classification":"node test/length-token-classification.test.mjs","check:off-grid-spacing-scale-mode":"node test/off-grid-spacing-scale-mode.test.mjs","check:jsts-extraction-completeness":"node test/jsts-extraction-completeness.test.mjs","check:prefer-token-class-downgrade":"node test/prefer-token-class-downgrade.test.mjs","check:similar-conditional-children":"node test/similar-conditional-children.test.mjs","check:start-inventory-dirs-backfill":"node test/start-inventory-dirs-backfill.test.mjs","check:off-grid-spacing-identity-scale":"node test/off-grid-spacing-identity-scale.test.mjs","check:ghost-tokens-observed-fabrication":"node test/ghost-tokens-observed-fabrication.test.mjs"},"version":"0.2.18","_npmUser":{"name":"deepadalja","email":"thedeepadalja@gmail.com"},"keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"_npmVersion":"10.9.7","description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","directories":{},"maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"_nodeVersion":"22.22.2","dependencies":{"zod":"^4.3.6","postcss":"^8.4.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.0"},"peerDependencies":{"typescript":">=5","puppeteer-core":">=20"},"peerDependenciesMeta":{"typescript":{"optional":true},"puppeteer-core":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dna_0.2.18_1790626469235_0.21558630849825566"}}},"time":{"created":"2026-08-09T22:16:36.308Z","modified":"2026-09-28T20:14:29.512Z","0.2.1":"2026-08-09T22:16:36.664Z","0.2.2":"2026-08-09T22:25:16.266Z","0.2.3":"2026-08-12T02:55:56.003Z","0.2.4":"2026-08-12T13:49:16.446Z","0.2.5":"2026-08-12T17:25:37.677Z","0.2.6":"2026-08-12T17:46:09.770Z","0.2.7":"2026-08-12T18:14:03.286Z","0.2.8":"2026-08-12T18:51:33.922Z","0.2.9":"2026-08-12T19:27:19.226Z","0.2.12":"2026-08-12T21:05:17.945Z","0.2.13":"2026-08-12T22:28:53.470Z","0.2.14":"2026-08-13T04:10:50.478Z","0.2.15":"2026-08-14T18:52:22.354Z","0.2.16":"2026-08-17T20:43:19.530Z","0.2.17":"2026-08-18T20:33:32.662Z","0.2.18":"2026-09-28T20:14:29.334Z"},"author":{"name":"DeepReidy","email":"deep@reidy.ai"},"license":"FSL-1.1-MIT","keywords":["design-system","design-tokens","conformance","lint","drift","design-identity","css","tailwind","provenance"],"description":"Design-system conformance: extract a codebase's design identity (.dna/identity.yaml, with per-rule provenance), then keep source AND rendered output conformant to it. Framework-agnostic: resolvers → normalized IR → generic rules.","maintainers":[{"name":"deepadalja","email":"thedeepadalja@gmail.com"}],"readme":"# @calibrate-ds/dna\n\nDesign-system conformance for codebases that have a design identity — or need one\nextracted. `dna` reads what your codebase already believes (tokens, type scale, spacing\ngrid, observed colours), records it as `.dna/identity.yaml` with **per-rule provenance**\n(`{ value, from, at }` — which side held authority, and when), and then keeps both your\n**source** and your **rendered output** conformant to it.\n\n## Requirements\n\nNode.js >= 18.17.\n\n## Installation\n\n```\nnpm install -g @calibrate-ds/dna\n```\n\nOr run it one-off with no install, via `npx` — note the full package name (`dna`\nalone resolves an unrelated package on npm):\n\n```\nnpx @calibrate-ds/dna check\n```\n\nOnce installed globally, the `dna` command is available directly:\n\n```\ndna check     # → \"No identity found — nothing to check. Run `dna start` …\"\ndna start     # extract the identity + a starter config from this codebase\ndna check     # now it checks — and it is clean on the code it extracted from\n```\n\n### Starting from a Figma design system\n\nIf your design tokens live in Figma (via the CalibrateDS plugin or otherwise), `dna`\ndoesn't import a token file directly — it only ever extracts from real, checkable\nsource in your own codebase, the same as everything else it does. The reliable path:\nexport the plugin's **`.tokens.css`** format (real CSS custom properties, including\n`var()` aliases), commit it into your repo, and either add it to `tokenSources` in\n`ds-lint.config.json` or just run `dna start` with it present under an `includePaths`\ndirectory — `dna` reads it through the same `postcss`-based extractor it uses for any\nother CSS, with the same tier inference, alias resolution, and fabrication guards.\nVerified directly against a real, 200+-variable plugin export: colors, aliases, and\ntiers all extract correctly with zero manual cleanup. Length-valued semantic tokens\n(`--font-size-*`, `--spacing-*`, `--border-radius-*`/`--radius-*` aliasing a raw scale\nvia `var()`, e.g. `--font-size-body-md: var(--scale400)`) are classified by what they\nactually RESOLVE to, not by reference syntax — they route into `scales.type`,\n`scales.spacingObserved`, and `scales.radius` respectively, the sections that actually enforce\ntype/spacing/radius membership, rather than landing in `palette` or a generic\n`declaredScale` bucket. A plain (non-semantically-named) length custom property still\nfalls back to `scales.declaredScale`, used by `off-grid-spacing`'s scale mode. All four\naxes — palette, type, spacing, radius — are enforceable from a `.tokens.css` import with\nzero manual cleanup. The CSV/JSON/JS export formats aren't a supported input today;\n`.tokens.css` is the one that goes through `dna`'s real, hardened parser rather than a\nbespoke importer.\n\n## Commands\n\n| Command | What it does |\n|---|---|\n| `dna start` | Extract an identity → `.dna/identity.yaml` (palette with tiers inferred from the resolution graph, type scale, observed-in-usage values annotated for review — the extractor surfaces, never silently drops). Writes a starter config in bare projects. |\n| `dna check` | The gate, diff-default: lint (tokens/literals/grid/scale) · cn-merge guard · rendered conformance (headless Chrome, needs `puppeteer-core`) · structural manifests. `--audit` for the whole tree, `--only=lint,cn,render,manifest`, `--config=<path>` to read a ds-lint config other than `ds-lint.config.json` — the default file being absent is fine (built-in defaults apply, noted with one `ℹ no ds-lint.config.json — built-in defaults` line); an **explicit** `--config` path that does not exist fails loudly instead (exit 1, names the path) rather than silently falling back to defaults. `--config` is honoured the same way by every other command that reads the ds-lint config — `doctor`, `hook install`, `similar`, `inventory`, `start`, `resolve`, and `allow` — not just `check`. |\n| `dna resolve <value>` | Reverse-lookup a raw value → identity token. Given a colour (`#2E7D32`, `#2e7d32`, or the equivalent `rgb(...)` — all resolve identically; also `hsl()`, `hwb()`, `oklch()`, `oklab()`, `lch()`, `lab()`, `color()` — see [Colour forms](#colour-forms)) or a length (`16px`/`1rem`), prints the matching identity token name(s) labeled by axis; a value on multiple scales (type/spacing/radius) reports **all** of them. The proactive counterpart to `dna check` — author in the token vocabulary first pass instead of writing a literal and getting it flagged after the fact. Tri-state and honest: a well-formed value that isn't in your identity prints \"not a token\" (no green tick), no identity prints the `dna start` prompt, and malformed input is a clean error. Detector only — reads the identity, writes nothing. |\n| `dna allow <axis> <value> --why \"<reason>\"` | Adopt a deliberate arbitrary value (`type`/`radius`/`color`/`spacing`) directly into `identity.yaml`'s enforced section — immediate effect on the next `dna check`, no `dna start` re-run, no hand-editing YAML. `--as <name>` names it (required for `radius`/`color`). Stamps provenance and appends to `.dna/decisions.jsonl`. Adoptions survive `dna start --force` on **all four axes**, value *and* provenance verbatim, whether or not a fresh scan still finds the value in source — the survival rule is by PROVENANCE SOURCE (any `from` other than `code`, so `dna allow` entries and hand-recorded ones alike), not by axis. A value the fresh scan no longer sees is kept and annotated `adopted; not seen by the static scan (may be used from data or dynamically) — delete only if obsolete`, never silently dropped and never silently relabelled `from: code`. (That note deliberately does not claim the value is unused: a static scan cannot see a colour held as data in a TS file and rendered dynamically.) |\n| `dna inventory [--json]` | The component vocabulary, parsed fresh from code: name · props · use-when · path. Read it at session start — the component failure mode is ignorance, not defiance. |\n| `dna similar` | Two advisory duplication checks over the same scorer (role-normalized shape + class shape, asymmetric containment), diff-default (`--audit` for the whole tree). **(1) Rebuild of an existing component** — changed JSX scored against the component library (\"you rebuilt `<Metric>` by hand\"). **(2) Clone of a net-new shape** — near-identical subtrees clustered across the scanned files themselves, reporting a shape repeated ≥2× with *no* backing component (\"extract one and reuse it\") — the case rebuild-matching is structurally blind to, since neither copy has a library entry to match against. **Both are advisory (exit 0), never gating** — see MAINTAINERS.md non-negotiable #2. See [`similar` config](#similar-config) below to tune it. |\n| `dna shapes [--json]` | Derive a component set from committed design-frame dumps (distribution-ranked, rule of three). |\n| `dna gen-manifest` | Structural screen manifests from design frames (`Sec-*` children, y-order). |\n| `dna figma diff --fresh=<dir> [screen]` | **Advisory, optional, hermetic** structural change detector. Diffs a freshly-produced dump against the committed baseline dump and reports the `Sec-*` section delta per screen — sections **added**, **removed**, and **reordered** (same set, new y-order — a distinct category). See below. |\n| `dna hook install [--config=<path>]` | Pre-commit hook running `dna check --only=lint,cn` — the static gate only; `render` (headless Chrome) and `manifest` are too slow/environment-dependent for every commit and belong in CI or an explicit `dna check --only=render,manifest` instead. Prefers the project-local `./node_modules/.bin/dna` so the hook runs the version your `package.json` pins, falling back to `dna` on `PATH` for global-only installs. Refuses to overwrite an existing `.git/hooks/pre-commit` it didn't write itself — pass `--force` to replace a foreign hook (its content is lost once you do, so back it up first if you need it). Re-running over its own prior install always proceeds without `--force`, and prints that the previous dna-installed hook was replaced (so a hand-edit made directly to it isn't silently lost — this includes replacing a hook that was installed with a *different* `--config`). Pass `--config=<path>` to have the installed hook's own `check` call carry that same `--config` on every commit, so a project reading its ds-lint config from a non-default location stays covered by the pre-commit gate too; omitted, the hook body is byte-identical to before this flag existed. `dna start` prints a one-line reminder to run this when the project is a git repo and no dna-managed hook exists yet. |\n| `dna agent-block` | Insert or refresh the dna agent-instruction block (the same one `dna start` writes — see \"Agent self-enforcement\" below) in `CLAUDE.md`/`AGENTS.md`, without re-extracting an identity. Inserts the block if the delimiters are absent (creating `CLAUDE.md` if neither file exists), replaces only the delimited region if present, and writes nothing when the computed content is already byte-identical — run twice and the second run reports \"already up to date\". Works with or without an identity present, since the block's own wording never depends on one. `dna check` warns (non-failing) when an identity exists but the block is missing from both files, naming this command as the fix. |\n| `dna doctor [--json] [--config=<path>]` | One-screen integration status: is the harness actually wired in, not just installed? Each line is one of four statuses with the one fix command: `ok` (present and right — nothing to do, never carries a `fix`), `warn` (present but not right — action recommended: a stale identity, a pre-commit hook whose body is outdated, or a local/PATH version mismatch), `missing` (not there at all), or `unknown` (can't be determined, e.g. no git — never a guessed state). Includes: (1) identity present + age/staleness (stale → `warn`, names `dna start --force`), (2) `.dna/identity.yaml` tracked in git (not ignored), (3) agent-instruction block present in `CLAUDE.md`/`AGENTS.md`, (4) pre-commit hook present, dna-marked, and whether its body matches what `dna hook install` currently ships (outdated body → `warn`, names `dna hook install`, no `--force` needed to replace dna's own hook), (5) `dna mcp` registered in a project-level `.mcp.json` (per-user client configs report \"unknown — not checked\", never guessed), (6) a CI step invoking `dna check` — a heuristic scan of `.github/workflows/*.yml`, `.gitlab-ci.yml`, `pipelines/*.yml`; \"not detected\" is not \"absent\" (an indirect invocation, e.g. via an npm script, isn't seen), (7) which `dna` would actually run — `./node_modules/.bin/dna` vs. `dna` on `PATH` (mismatch → `warn`, names running via the local install or aligning the global), (8) the `rules` line — which ds-lint config it actually read (`--config`, same flag and same `loadConfig` `dna check --config` uses; omitted reads the default `ds-lint.config.json`, missing default → \"config: none found — built-in defaults\"; a named `--config` path that doesn't exist → `missing`, not `unknown`, naming the path) plus which rules are active/off and why. Read-only, advisory: never fixes anything, never writes, exit 0 always. No git repo → lines 2 and 4 report \"unknown — not a git repository\" rather than a guessed state. Exposed as the `dna_doctor` MCP tool with the same structure, plus an optional `config` input mirroring this `--config`. |\n\n### `similar` config\n\n`dna similar` is tuned with a `similar` config namespace (`core/similar.mjs` L43-46,\n274, 318):\n\n```json\n\"similar\": { \"threshold\": 0.8, \"minEvidence\": 8, \"exclude\": [], \"enabled\": true, \"minCoverage\": 0 }\n```\n\n- **`threshold`** (default `0.8`) — the minimum containment score (how much of a\n  candidate subtree a library component's feature bag explains) for a rebuild match.\n- **`minEvidence`** (default `8`) — the minimum feature-bag size a subtree/component\n  needs to be compared at all; tiny bags match everything, so anything smaller is\n  skipped by both the rebuild and clone passes.\n- **`exclude`** (default `[]`) — library component names too structurally generic to\n  match on (e.g. a plain icon+text link that matches every icon+text row). Excluded\n  from the rebuild pass, and a clone cluster that resembles an excluded component is\n  treated as already backed, so it isn't clone-reported either.\n- **`enabled`** (default `true`) — set `false` to turn the rule off without losing the\n  rest of the config.\n- **`minCoverage`** (default `0`, disabled — issue #216) — an ADDITIONAL, opt-in floor on\n  top of the rebuild pass's existing, unconditional \"size comparability\" guard (a\n  candidate must already be ≥50% of the matched component's feature-bag size before its\n  score is even computed — unaffected by this knob). Coverage = the candidate subtree's\n  feature-bag size ÷ the matched library component's feature-bag size (smaller ÷ larger,\n  the same multiset sizes the built-in 50% guard already compares). A rebuild match is\n  reported only when this coverage is **≥ `minCoverage`**, in addition to `threshold` and\n  the built-in guard — raise it above the default to require more of a component's shape\n  to be present before flagging a small fragment as a rebuild (the Reidy `LendingListPanel`\n  case: a small subtree matching a large library component at 80%+ containment while only\n  covering a modest fraction of its size). `minCoverage: 0` means \"at least 0% coverage\",\n  which every match already satisfies, so the default changes nothing — output is\n  byte-identical to before this knob existed. Values at or below `0.5` change nothing\n  either way: the built-in size guard already excludes any candidate below 50% of the\n  component's bag, so the useful range is `0.5` to `1`. A match dropped for coverage is never\n  silently dropped: it's counted and printed once per run\n  (`N match(es) below similar.minCoverage (<value>) — not reported; raise or lower the\n  knob`), plus the dropped pairs (`file:line`, matched library component, coverage), and\n  carried on the result object (`droppedForCoverage: { count, matches }`) and the\n  `dna_similar` MCP payload. Only affects the REBUILD pass (pass 1) — the clone/all-pairs\n  pass (pass 2) clusters candidate subtrees against each other, not against the library, so\n  a per-component coverage floor has no meaning there and pass 2 is untouched by this knob.\n  A value that isn't a number in `[0, 1]` is reported as a named config warning (`similar.\n  minCoverage must be a number in [0, 1] — got …; ignored, using the default (0,\n  disabled)`) and the knob is ignored — never an invented fallback.\n\nSince #163, JSX behind a conditional (`&&`/`||`/`??`, both ternary branches) counts as a\nstructural child like any other, so a component built mostly from conditional sections\nis no longer scored as small/generic on that basis alone — an `exclude` entry added to\nwork around that specific false-positive class may now be redundant; worth rechecking\nbefore carrying it forward.\n\n### `dna figma diff` — structural change detector\n\n`dna figma diff --fresh=<dir>` answers \"what changed structurally in the frames since I\nlast looked?\" without touching the network. It's **optional and advisory** — most useful\nto a team still treating Figma as a source of truth. dna is code-first, so a frame change\nis *information*, not automatically a code violation; this ships as a reporting command,\nnever a gate.\n\n- **Baseline vs fresh.** The **baseline** is the committed dump `gen-manifest` already\n  reads, `<cacheDir>/<screen>.figma.json` — the last frame state you accepted into git.\n  The **fresh** dump is one you just produced (the identical extractor step\n  `gen-manifest` uses, aimed at a scratch directory) and pass via `--fresh=<dir>`; per\n  screen the fresh file is `<dir>/<screen>.figma.json`. One invocation diffs every\n  configured screen; pass a screen name to diff just one.\n- **Hermetic.** Pure local dump-vs-dump. dna never fetches a dump, reads no credentials,\n  and has no network-capable import — same isolation guarantee as `dna check`.\n- **Structural only.** Reports the `Sec-*` section delta (added / removed / reordered),\n  reusing the exact prefix-filter + y-order + schema-validation path `gen-manifest` uses.\n  A malformed baseline or fresh dump fails **loud** at validation (naming the file and\n  the bad node), never a silent wrong or empty delta. Token-value and shape deltas are\n  deliberately out of scope for now (future, separate axes).\n- **Tri-state, middle never green.** `pass` (✓, both dumps present and structurally\n  identical) · `no-op` (•, no baseline — or no fresh — dump to diff against, naming the\n  reason) · `delta` (Δ, a real structural change). A no-op never renders as a green tick.\n- **Exit convention.** Advisory: a real structural delta reports and exits `0` (like `dna\n  similar`). The only non-zero exit is a hard error — a malformed dump (schema\n  validation) or a missing `--fresh` argument — i.e. \"couldn't compute a trustworthy\n  answer\", not \"the frames changed.\"\n\n### `dna check --only=render` — rendered conformance\n\nRenders the routes listed in `check-rendered.config.json` in headless Chrome (needs the\noptional `puppeteer-core` peer and a system Chrome) and asserts that token classes /\n`data-ds-size` roles actually compute to their token value in the DOM.\n\n```json\n{\n  \"scopePaths\": [\"src\"],\n  \"rootSelector\": \"#root\",\n  \"routes\": [\n    { \"path\": \"/\" },\n    { \"path\": \"/confirm\", \"waitFor\": \"[data-screen=confirm]\" },\n    { \"path\": \"/settings\", \"minElements\": 8 }\n  ]\n}\n```\n\nEvery `routes` entry must be an object of this shape — a plain string, or an object\nmissing `path`/with `path` not starting with `/`, fails the whole run by name with\nreason `invalid-routes` (naming each bad entry by index) before anything is probed,\nspawned, or launched; an entry with an unrecognized key is only warned by name, never\nfailed.\n\n- **Readiness, per route.** A route is inspected once its ready selector exists —\n  `waitFor` if set, otherwise the fallback `rootSelector` (default `body`).\n  - With an explicit `waitFor`, that selector *is* the \"did it render\" signal: no\n    element-count floor applies, so a legitimately small screen (a confirmation card)\n    is inspected normally.\n  - Without `waitFor`, the fallback selector must also hold at least `minElements`\n    descendant elements (default `21`), because the app shell can exist before the\n    screen does. Set `minElements` per route to lower or raise that floor (`0` disables\n    it). A `minElements` set alongside `waitFor` is honoured too; a value that isn't a\n    non-negative integer fails that route rather than being silently defaulted.\n- **It does not inspect, or kill, a server it did not start.** Three separate guarantees,\n  and the last two hold regardless of how the first one goes:\n  - *Refuse an occupied port.* Before spawning anything, the port (`port`, default `5174`)\n    is probed on the pinned host plus the **loopback addresses** — `127.0.0.1` and `::1`,\n    which `localhost` may resolve to either of, plus whatever `localhost` resolves to on\n    this machine. If anything already holds it, the step refuses outright:\n    `✗ check:rendered — port 5174 is already in use by another process; the render check\n    did not run. Stop it or set a different \"port\" in check-rendered.config.json.` —\n    status `fail`, exit `1`, nothing inspected, and the teardown backstop **does not run**.\n    The port is never silently changed for you: your config says which port, and quietly\n    moving would hide the problem. If the dev server this step spawned exits before the\n    port answers (a port clash, a broken vite config, a crash), that is named immediately —\n    `✗ check:rendered — the dev server exited before it was ready (exit code 1); the render\n    check did not run.` with a bounded tail of its stderr — never a 30-second wait timeout\n    and never a false \"ready\". In that case too the backstop stays off: a server that never\n    became ready never owned the port, so whatever is listening there is not ours to kill.\n  - *The server it inspects is the server it spawned.* vite is bound to **one literal\n    address** (`host`, default `127.0.0.1` — never the name `localhost`), and the readiness\n    poll and every navigation use that exact same literal. A connection is always served by\n    the most specific bound socket, so a foreign wildcard (`0.0.0.0`) listener — which on\n    macOS/BSD can share the port without either bind failing — can never answer in our\n    server's place; and if a foreign process holds that exact address, our own bind fails\n    and the early-exit message above names it. Set `host` only if your app genuinely needs\n    a different address; a name (rather than a literal) reopens the ambiguity this closes.\n    A `host` you do set must be a literal, non-wildcard IP address (IPv4/IPv6, bracketed\n    IPv6 accepted) — a hostname (`localhost` included), a wildcard/unspecified form\n    (`0.0.0.0`, `::`), a scoped IPv6 literal carrying a zone id (`fe80::1%en0` — a\n    link-local address means nothing without its interface and has no URL form Chrome can\n    navigate to), or a value carrying a scheme/port/path is rejected before anything\n    is probed, spawned, or launched: `✗ check:rendered — \"host\" must be a literal IP\n    address (e.g. \"127.0.0.1\" or \"::1\"), not \"<value>\"; the render check did not run.`\n    Leaving `host` unset (missing, blank, or non-string) is \"not set\", not \"set wrong\" —\n    it always falls through to the default and is never affected by this check.\n  - *The teardown backstop kills only its own process group.* vite's esbuild children can\n    outlive the signal sent to the dev server, so surviving listeners on the port are\n    SIGKILLed — but sharing a port *number* was never evidence of ownership. The dev server\n    is spawned detached, leading its own process group, and only listeners whose process\n    group is that child's are killed. Anything else is left running and named in one line:\n    `⚠ check:rendered left tcp:5174 listener pid 4242 alone: not started by this run.`\n    If ownership cannot be established at all (no `ps`, unreadable `ps` output), **nothing\n    is killed** and the refusal is reported rather than silently skipped:\n    `⚠ check:rendered port backstop skipped: could not establish process-group ownership\n    (unrecognised ps output); nothing was killed. …` Neither line changes the exit code or\n    the tri-state status. (Windows is unchanged: the backstop does not run there.)\n- **Each route stands alone.** A route that can't be inspected is reported by path with\n  the wait that failed — `✗ /confirm — selector wait failed: … (selector [data-screen=confirm])`\n  or `✗ / — content-count wait failed: … (selector #root)` — and the remaining routes\n  still run. Any failed route (a failed wait or an identity violation) makes the step\n  exit `1`.\n- **Redirects are never a pass.** If the browser ends on a different path than the one\n  requested (a guarded route bouncing to sign-in), the route prints\n  `⚠ /verify — redirected to /signup; the requested route was not inspected` and counts\n  as **not verified** — not a pass, not a violation. Only the path is compared (trailing\n  slash and query string ignored; the hash is compared only when the configured route\n  itself contains one). To verify a guarded screen, give the check a route that renders\n  it without the guard.\n- **The summary reconciles.** The last line always accounts for every configured route:\n  `routes: 3 configured = 1 passed + 1 failed + 1 not verified (1 redirected)`. A run\n  where no route was verified (all redirected, or nothing token-classed to inspect) is a\n  `no-op`, never a green tick; a pass that left some routes unverified says so.\n- **A palette entry with no declared custom property is named, not silently skipped.** The\n  probe can only check a token that has a real `var(--x)` to look for — a colour that's\n  only ever been *observed* in usage, defined solely in a Tailwind config, or adopted via\n  `dna allow color` has nothing to probe, so it's excluded before the probe runs and named\n  once at the end of the run: `⚠ 2 colour token(s) with no declared custom property — not\n  render-checkable: blue-dark, brand-hover`. This is a different reason than the\n  `⚠ N colour token(s) not verifiable by the render probe (neither hsl(var(--x)) nor\n  var(--x) resolved)` line above it — that one means a declared token's value couldn't be\n  matched at runtime; this one means there was no declared value to try in the first place.\n  Neither line changes `checked`, counts as a violation, or affects the exit code/status.\n\n## MCP server\n\n`dna mcp [--cwd=dir]` runs a standalone MCP server that exposes `dna`'s findings as\nstructured data to an MCP client (an AI IDE/chat), instead of a human reading CLI\noutput. `--cwd` sets the project root to operate on; it defaults to the MCP client's\nworkspace root, else the server process's own `cwd`. Independent of the `@calibrate-ds/\ncli` MCP server — no shared code, no shared process.\n\n| Tool | What it does |\n|---|---|\n| `dna_check` | Run `dna`'s design-system conformance check and return the findings as structured data (rule, severity, file, line, value, and an optional \"what would satisfy this\" hint) — the same findings `dna check` prints to stdout and logs to `.dna/log.jsonl`. Also returns `steps` — one entry per step (`lint`, `cn`, `render`, `manifest`) reporting what it actually verified: `cn`'s status is `pass`/`fail` (with `pairs` checked, and on `fail` the `failingPairs` cn is dropping) / `no-op` (`cn.module` not configured — reason `cn-not-configured`) / `unavailable` (the project's cn() helper couldn't be loaded at all — one of the five `cn-deps-missing`/`cn-import-not-found`/`cn-syntax-error`/`cn-no-export`/`cn-load-failed` reasons, no stack trace) / `not-run` (excluded via the `only` input). Takes optional `config` (ds-lint config path, mirroring `dna_doctor`'s `config` and the CLI's `dna check --config` — reaches the `cn` step too, matching #214/#215) and `only` (an array of `lint`/`cn`/`render`/`manifest`) inputs — `only` mirrors the CLI's `--only` **exactly**, including `lint` itself: excluding `lint` here reports `steps.lint.status === \"not-run\"` and removes `findings`/`summary` from the payload entirely (never an empty array/zero counts standing in for \"lint didn't run\"), and if every step is excluded, `status` is `\"no-op\"`, never `\"pass\"` — nothing ran, so nothing passed. `only` omitted runs every step, and the payload is otherwise unchanged from before this field existed. Detector only: this never edits source, config, or anything outside `.dna/` — use the returned findings to make your own edits with your own tools. |\n| `dna_inventory` | Return `dna`'s current component inventory (name, props, one-line \"use when\" description, file path) as structured data — the same data `dna inventory --json` prints. Check this before building a new component: a component that looks missing may already exist under a different name. Each entry also carries `descriptionSource`: `own` (the component's own JSDoc/comment), `file` (fell back to a file-level header comment), or `none` (no description found anywhere). Read-only — this tool never writes anything. |\n| `dna_similar` | Run `dna`'s structural duplication check and return the findings as structured data, each tagged with `kind`: `\"rebuild\"` (a hand-rebuild of an existing component — file, line, matched component name/path, score) or `\"clone\"` (a net-new shape repeated across files with no backing component — size and the list of occurrences to extract). Same findings `dna similar`/`dna similar --audit` prints. Call this (alongside `dna_inventory`) before writing new component code: it catches reinvention that slips past a name-only inventory check, and net-new shapes being cloned across files. Detector only. |\n| `dna_resolve` | Reverse-lookup a raw design value to the project's identity token(s): given a colour (hex like `#2E7D32`, or `rgb()`/`rgba()`/`hsl()`/`hwb()`/`oklch()`/`oklab()`/`lch()`/`lab()`/`color()` — see [Colour forms](#colour-forms)) or a length (e.g. `16px`, `1rem`), returns the matching token name(s) labeled by axis — a value on multiple scales (e.g. both a spacing step and a radius step) reports **all** of them, never one. The same lookup `dna resolve <value>` prints. Call this **before** writing a raw literal pulled from a design/frame, so you author with the token instead of a hardcoded value — the proactive counterpart to `dna_check`. Tri-state and honest: `resolved`, `not-a-token`, `no-identity`, or `invalid`. Detector only — never writes. |\n| `dna_doctor` | One-screen integration status — the same checks `dna doctor` prints, as structured data: `{ checks: [{ id, status, detail, fix }], summary: { ok, warn, missing, unknown } }`. `status` is `ok` (nothing to do — never carries a `fix`), `warn` (present but not right — action recommended), `missing`, or `unknown`. `fix` names the one command/edit for a `warn`/`missing` line, or is `null` when nothing needs fixing. Takes an optional `config` input (ds-lint config path, relative to the project root) that the `rules` check reads from — mirrors `dna doctor --config`, and reads the config through the same `loadConfig` `dna check --config` uses: omitted reads the default `ds-lint.config.json` (missing is fine), an explicit path that doesn't exist reports the `rules` check as `missing`, naming the path. Read-only and advisory — never fixes anything or writes anything. |\n| `dna_start_preview` | Preview what `dna start` would extract and write — the palette (declared + observed-in-usage), type scale, spacing grid/scale, radius scale/idioms, Tailwind color families, and per-rule provenance annotations — as structured data, WITHOUT writing anything to disk. Use this to show a user what `dna start` is about to set up before they run it themselves. Preview only: `dna start` itself (CLI, user-initiated) is the only thing that writes. |\n\nEvery tool is detector-only — none of them ever write source, config, or anything\noutside `.dna/`; a calling agent uses the returned findings to make its own edits with\nits own tools. `dna_check`'s payload also folds in the optional `render`/`figma`\nsub-checks (rendered conformance, structural manifests) when those peers are installed\nand configured, matching the CLI's own `dna check` behavior.\n\nThose sub-checks also report themselves in an additive `steps` object, so zero findings\nfrom a step is never mistaken for \"it passed\" — the tri-state rule applied to the surface\nagents actually read:\n\n```jsonc\n\"steps\": {\n  \"render\": {\n    \"status\": \"pass\",        // \"pass\" | \"no-op\" | \"fail\" | \"unavailable\" | \"not-run\"\n    \"routes\": { \"configured\": 3, \"passed\": 3, \"failed\": 0, \"notVerified\": 0 },\n    \"checked\": 29,           // elements verified — the number in the CLI's ✓ summary line\n    \"notices\": [\"⚠ …\"]       // present only when there were any\n  },\n  \"manifest\": { \"status\": \"no-op\", \"reason\": \"no-config\" }\n}\n```\n\nBoth keys are always present. `unavailable` means the optional module is not installed;\n`not-run` means the step was never reached (today: no identity).\n\n`reason` names *which* no-op it was, and — for a failure the step could not even start —\nwhich one. It is present on every `no-op`, and on a `fail` that never got as far as\ninspecting routes. It is **absent** on a `pass`, and absent on a `fail` produced by the\nroutes themselves (identity violations, or routes that could not be inspected): there the\n`routes` counts and the findings say what happened, so there is nothing a single word\nwould add. Values — for `render`: `no-config`, `no-identity`, `unresolvable-base`,\n`no-changes`, `no-puppeteer-core`, `no-chrome`, `no-routes`, `invalid-host`,\n`invalid-routes`, `every-route-redirected`, `no-token-classed-elements`, `no-route-verified`,\n`port-occupied`, `child-exited`, `not-ready`, `could-not-run`; for `manifest`: `no-config`,\n`no-manifests`, `typescript-unavailable`, `screen-not-found`. `notices` carries lines the\nstep printed that are neither findings nor its status (the port-teardown backstop's\nskip/left-alone lines, colour tokens the render probe could not verify).\n\n`dna_check`'s payload also conditionally includes a few purely-informational fields —\npresent only when they apply, absent otherwise, and never affecting `status` or exit\ncode: `ruleWarnings` (config `rules` keys that match no known rule, so they do nothing),\nand `malformedLedgerLines` (one entry per invalid-JSON line found in\n`.dna/decisions.jsonl` this run — e.g. an unresolved git merge conflict marker — the\nsame non-failing warning `dna check` prints on stdout; the line itself is left as-is,\nnever rewritten or dropped).\n\nTo make this self-serve for an agent working in a consumer project, `dna start` (and\n`dna start --force`) auto-writes a short, delimiter-scoped instruction block into that\nproject's own `CLAUDE.md`/`AGENTS.md`, telling a coding agent to call `dna_inventory`/\n`dna_similar` before creating a new component, `dna_resolve` before writing a raw value\npulled from a design/frame (to author with the token instead of a literal), and\n`dna_check` after editing a design-relevant file — on its own initiative, no manual step\nrequired from the human,\nas long as `dna mcp` is configured as an MCP server in the agent's client. This is a\ncooperation convention, not an enforcement guarantee — `dna hook install`'s pre-commit\nhook remains the real backstop regardless of whether an agent follows it.\n\nIf that block is ever lost (a hand-edit, a merge conflict, a regenerated convention\nfile), restore it with `dna agent-block` — a cheap, standalone command that does the\nsame delimiter-scoped insert/replace `dna start` does, without re-extracting an\nidentity. `dna check` also warns (non-failing) when an identity exists but neither\n`CLAUDE.md` nor `AGENTS.md` carries the block, so this never goes silently missing.\n\n`dna check` separately warns (also non-failing) when `.dna/identity.yaml` exists in a\ngit repo but is untracked or git-ignored — a common cause is a broad `.dna/` ignore\nrule (see #93 below); an identity that lives on only one machine means CI and everyone\nelse's `dna check` is checking nothing shared.\n\n## CI / Team Usage\n\n### What to commit\n\n`.dna/` holds four files with genuinely different commit semantics — treat them\nasymmetrically, not as one directory to gitignore wholesale:\n\n| File | Commit? | Why |\n| --- | --- | --- |\n| `.dna/identity.yaml` | **Commit** | The shared design-system record — the whole team reads the same palette/scales/families. Not derived output; it's a record, never overwritten without `--force`. **Hand-maintain it after the first `dna start`.** `dna start --force` is a full re-extraction that **merges with what is already in the file** — it does not start blank. **Values** are always re-derived from source. Everything below survives it. (1) **Provenance other than `from: code`** — `dna allow` adoptions, `from: figma`, `from: design`, anything you recorded by hand — kept verbatim on all four axes, value *and* `from`/`at`/`reason`, even when the fresh scan no longer observes the value (it is then annotated `adopted; not seen by the static scan (may be used from data or dynamically) — delete only if obsolete`, which deliberately does not claim the value is unused — a static scan cannot see a colour held as data and rendered dynamically). (2) **Hand-written `reason:` text** on a `from: code` entry — carried through, including when the value changed, where the diff additionally flags it as possibly out of date rather than deleting it. (3) **Hand-written trailing `# comments`** — on **every** entry axis (palette / type / spacing / radius / `declaredScale` / `spacingObserved` / `fontSizeObserved`) and on `families.allowed` items and `radiusIdioms` labels, preserved verbatim. A standalone comment line sitting **above a block's first entry** is kept too, re-emitted at the top of that block; one that belongs to no block dna re-writes (above the first section, between blocks, or trailing the file) cannot be — and is not silently dropped either: the diff names the exact line and says where to move it to keep it. When a generated review note also applies, your comment comes first and the generated note is appended after ` · ` (`# keep: deliberate one-off · seen 3× in usage — REVIEW: token or delete`); on the next run that generated half is recognised and replaced, never accumulated. (4) **`at` stability** — an entry whose value did not change keeps the date it was set. `at` moves only on a new entry, a changed value or changed authority, so re-running `--force` on an unchanged project on a later day is byte-identical and reports \"identity unchanged\" instead of re-stamping every line with today's date. (5) **Seed authorship** from a configured `provenanceSeed` is re-applied on every extraction by rule match — so a seed-governed entry is re-derived from the seed file rather than frozen (the seed file, not this file, stays authoritative for those), and if the seed supplies a `reason` it replaces any reason recorded here, with the diff naming both. Remove a seed rule later and the entry it governed does **not** revert to `from: code` — it becomes a preserved entry as-is, since this file is then the only remaining record of that authority. What is **not** kept is a value you edited by hand while leaving the entry marked `from: code` — indistinguishable from a fresh observation by construction, so it is recomputed away. **Change `from` when you change a value by hand** (and add an `at` and a `reason`) and the edit becomes permanent. Likewise, a hand-recorded entry that *is* covered by a seed glob and is no longer observed in source is re-derived to nothing and disappears — and if it carried a hand-written note, the diff reports it by name as `- <entry> … (had a hand-written note: \"…\")`, never silently. Every `--force` run over an existing identity prints a diff — entries added, removed, value-changed, **value-reformatted**, provenance-changed and annotation-changed, per **every** axis the file has (palette, type, radius, spacing, `declaredScale`, `spacingObserved`, `fontSizeObserved`, `radiusIdioms`, families and `history`, each listed even when unchanged) — and says \"identity unchanged\" explicitly when it changed nothing, so nothing moves silently. *Value reformatted* is a spelling change that renders identically (`#2E7D32` → `#2e7d32`, `rgb(46,125,50)` → `rgb(46, 125, 50)`, `12px` → `12.0px`): the entry keeps its `at` and provenance, because nothing was set that day, and the respelling is still reported rather than absorbed — no cross-unit or cross-colour-space equivalence is ever claimed (`1rem` is not `16px`). One generated note carries a marker of its own: a `# seen N×` review count this run could not re-derive is re-emitted as `# seen N× (prior scan)`, so a real but older count is never presented as the current one. |\n| `.dna/decisions.jsonl` | **Commit** | The append-only trust-decision ledger: every severity change/rule override, with a reason. A new teammate reads this to understand *why* a rule was disabled — without it, that context only exists in one person's local `.dna/` and is invisible to everyone else. Never edited or pruned by dna — when a file an `ignore`-type entry's `scope` points at is deleted or moved, `dna check --audit` warns \"N ledger entr(y/ies) reference paths that no longer exist\" and names them, so a human knows what to prune; a plain `dna check` (diff mode) stays quiet. A malformed line (invalid JSON — e.g. an unresolved git merge conflict's `<<<<<<<`/`=======`/`>>>>>>>` markers, since this file is committed and two branches can each append a decision) never crashes `dna check`: it's reported every run as a non-failing `⚠ .dna/decisions.jsonl:<line> is not valid JSON — skipped` warning (with a merge-conflict-specific hint when applicable), the line is left exactly as-is — never rewritten or dropped — and new decisions are still appended after it. Custom `ledgerDir`/`decisionsFile` are respected. |\n| `.dna/log.jsonl` | Gitignore | Per-run violation noise, rewritten on every `dna check`. Local scratch, not a record. Path overridable with `logFile` (default `<ledgerDir>/log.jsonl`). |\n| `.dna/state.json` | Gitignore | A severity cache plus the last full-audit summary (`lastAudit.lint` / `lastAudit.similar`: date and counts, written only by an `--audit` run of `dna check`/`dna similar`, each touching only its own key) — derived, not authoritative. Because it is gitignored local state, a fresh clone or CI has no record, and a diff-mode no-op there says `no full audit recorded yet — run with --audit` rather than quoting counts it does not have. Path overridable with `stateFile` (default `<ledgerDir>/state.json`). |\n\n`dna start` sets this up automatically: it writes or appends to your project's\n`.gitignore`, ignoring exactly `.dna/log.jsonl` and `.dna/state.json` (never the whole\n`.dna/` directory), so `identity.yaml` and `decisions.jsonl` are committed by default.\nRe-running `dna start`/`dna start --force` is idempotent — it won't duplicate entries\nthat are already there, and it never touches unrelated `.gitignore` content.\n\n**dna's design-history ledgers are exactly `.dna/identity.yaml` and `.dna/decisions.jsonl`\n— only those.** If your project keeps other design bookkeeping — a `token-provenance.jsonl`\nrecording per-token code↔design authority, a `design-deviations.jsonl` of intentional\ndifferences, anything similar — those are *your team's* conventions; dna neither writes\nnor reads them. In particular, `dna allow` writes to **exactly two** files: it adopts the\nvalue into `.dna/identity.yaml` and appends one line to `.dna/decisions.jsonl`, and nothing\nelse (so undoing a `dna allow` means reverting those two, not three). Beyond `.dna/`, the\nonly things dna ever writes are the ones it tells you about at the time: the starter\n`ds-lint.config.json` and the agent-instruction block in `CLAUDE.md`/`AGENTS.md` (both on\n`dna start`), a `manifests/*.json` (on `gen-manifest`), and `.git/hooks/pre-commit` (on\n`dna hook install`).\n\n**Recommended: add a `CODEOWNERS` entry for `.dna/identity.yaml`.** Changing the\ndesign system should go through a reviewed PR, not land as a silent commit buried in\nan unrelated change:\n\n```\n# CODEOWNERS\n.dna/identity.yaml  @your-design-system-owners\n```\n\n### `provenanceSeed` — importing prior authorship\n\nIf your project already knows *who* decided a value before `dna start` ever ran — a\ndesign review, a migration doc, an earlier hand-maintained record — you can feed that\nauthorship in so freshly-extracted identity entries carry it instead of a generic\n`from: code`. Point the config key at a JSONL file:\n\n```json\n{\n  \"provenanceSeed\": \"design/token-history.jsonl\"\n}\n```\n\n(a relative path, resolved from the project root — the file itself is yours to name and\ncommit; dna doesn't require or assume any particular filename).\n\nEach line is one JSON object, one entry per line:\n\n```json\n{\"rule\":\"palette.on-dark-panel-from\",\"from\":\"design\",\"at\":\"2026-01-01\",\"reason\":\"dark-mode panel gradient\"}\n```\n\n| Field | Required | Meaning |\n| --- | --- | --- |\n| `rule` | yes | Which identity entry this authorship applies to — see rule namespace below. |\n| `from` | no | The authority to record (e.g. `\"design\"`, a person, a team) — defaults to `code` when omitted. |\n| `at` | no | The date to record — defaults to today when omitted. |\n| `reason` | no | A human-readable note, rendered alongside the entry. |\n| `value` | no | Recorded for your own reference only — never read back by `dna start`; the extracted value always comes from source. |\n\n**Rule namespace — one rule per identity entry, no lists or joins.** `rule` matches\nexactly one entry's key, per axis (the full set, derived directly from every seed\nlookup `dna start` performs):\n\n| Axis | Rule form |\n| --- | --- |\n| Palette (declared or observed-in-usage) | `palette.<name>` |\n| Type scale | `scales.type.<name>` |\n| Spacing grid (the single grid value) | `scales.spacing` |\n| Spacing observed-in-usage candidates | `scales.spacingObserved.<name>` |\n| Font-size observed-in-usage candidates (JS/TS) | `scales.fontSizeObserved.<name>` |\n| Declared scale (raw CSS length custom properties) | `scales.declaredScale.<name>` |\n| Radius scale | `scales.radius.<name>` |\n\nThere is no list, alternation, or path-join syntax — `\"a/b\"`, `\"a + b\"`, and\n`\"a (note)\"` are not rule syntax, they're a single literal string that will match\nnothing. Write one seed line per entry instead. A rule also can't stop at a bare axis\nname (`\"scales.type\"`, `\"scales.radius\"`) expecting it to cover every entry on that\naxis — write `\"scales.type.*\"` instead (see glob below); `\"scales.spacing\"` is the one\nexception, since it addresses a real single-valued entry, not a per-name axis.\n\n**Glob (`*`) matching.** A `*` inside a rule matches any run of characters, so\n`\"palette.on-dark-*\"` matches `palette.on-dark-a`, `palette.on-dark-panel-from`, etc.\nWhen more than one rule matches the same entry, specificity decides the winner — by a\ndeterministic order, not by which rule string happens to be longer:\n\n1. **An exact rule (no `*` at all) always beats any glob**, regardless of length.\n2. **Among two globs, the one with more literal (non-`*`) characters wins** —\n   `\"palette.on-dark-*\"` (13 literal characters) beats `\"palette.*\"` (8) for an entry\n   both match, even though as raw strings they may differ from what plain length would\n   suggest.\n3. **A genuine tie** — two or more globs with the same literal-character count, all\n   matching the same entry — has no winner decidable from the rule text alone. `dna\n   start` reports it once as `⚠ ambiguous seed rules for <entry>: \"<a>\" and \"<b>\"\n   match with equal specificity — \"<used>\" was used` (every tied rule is named, not\n   just the first two, when three or more tie), and **none of the tied rules is ever\n   reported as a dead rule** (see below) — all of them genuinely matched. Which one is\n   used is deterministic, not random: seed-file order — among equally-specific rules,\n   whichever appears first in the seed file is used.\n\nSo a broad glob and a precise literal for one entry can coexist, with the literal\ntaking precedence.\n\n**The bare `\"*\"` rule is a global note, not per-entry authority.** It is never matched\nagainst individual entries; it's recorded once, verbatim, at the top of the generated\n`history:` block as a standing note for the whole file, and it is never reported as a\ndead rule (see below) since it isn't meant to match anything itself.\n\n**Dead rules are reported, never silent.** After extraction, `dna start` /\n`dna start --force` reports every seed rule (other than the bare `\"*\"`) that matched\nzero identity entries, printed with the rule text and its line number in the seed\nfile, plus a hint (unsupported syntax like a slash/`+`/parentheses, an axis-level rule\nmissing `.*`, or simply \"matches no identity entry\"). A rule that would only ever have\nmatched a value adopted via `dna allow` is reported separately as `adopted-only`,\nsince that entry's provenance is already self-preserving and doesn't depend on the\nseed. Malformed JSON lines in the seed file are reported by line number too, instead\nof being silently dropped. This is reporting only: which entry a live rule resolves to\nnever changes, the run never fails because of a dead or malformed line, and every\nseed line — dead or live — still renders into the generated `history:` block verbatim.\nThe same dead-rule list is included in the `dna_start_preview` MCP tool's payload when\nthere is at least one (omitted entirely, never an empty array, when there isn't).\n\n### CI\n\nThe pre-commit hook (`dna hook install`) only ever runs `--only=lint,cn` — the static,\nfast checks. `render` (headless Chrome) and `manifest` are the right checks to run in\nCI instead, either as part of the same `dna check` invocation below (drop `--only` to\nrun everything installed/configured) or as a separate `dna check --only=render,manifest`\nstep, since they're too slow and environment-dependent to gate every local commit.\n\nGate PRs on `dna check` in GitHub Actions by diffing against the PR's base commit,\nso the check only flags lines actually touched by the PR (not pre-existing issues\nelsewhere in the repo). `dna check` defaults to `--base=HEAD`, which isn't useful in\nCI — pass the PR's base SHA explicitly so the diff is computed against the branch\nbeing merged into, not the last commit on the PR branch itself.\n\n**`--base` takes the ref as `--base=<ref>` (equals sign, no space)** — the flag\nparser only recognizes the `--name=value` form; a space-separated `--base <ref>` is\nsilently ignored and the diff falls back to the `HEAD` default.\n\n```yaml\nname: dna check\n\non:\n  pull_request:\n\njobs:\n  dna-check:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0 # full history so the base SHA below is resolvable\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 20\n\n      - run: npx @calibrate-ds/dna check --base=${{ github.event.pull_request.base.sha }}\n```\n\n`fetch-depth: 0` matters here: with the default shallow checkout, the base commit\noften isn't present locally. `dna check` verifies `base` resolves before diffing and\nexits non-zero with `cannot resolve base ref '<ref>' — is the history shallow?\n(actions/checkout needs fetch-depth: 0)` when it doesn't — it will never silently\nreport \"nothing to check\" for an unresolvable ref.\n\n## Troubleshooting\n\n**`dna mcp` seems to hang / print nothing when I run it in a terminal.**\n\nThis is expected — it's not stuck or broken. `dna mcp` starts a standalone MCP server\nthat holds the process open on stdio, waiting for an MCP client to send it JSON-RPC\nmessages. Run directly in a terminal with no client attached, there's nothing to\nrespond to, so it just sits there until you `Ctrl+C`. It isn't meant to be run\nstandalone to \"see output\" — the real usage path is registering it as an MCP server in\nan IDE or chat client, e.g.:\n\n```\nclaude mcp add dna -- dna mcp\n```\n\nOnce a client is talking to it, `dna_check` / `dna_inventory` / `dna_similar` /\n`dna_resolve` / `dna_start_preview` become available as tools it can call — see [MCP server](#mcp-server)\nabove.\n\n**`Cannot find package '@modelcontextprotocol/sdk'` / `ERR_MODULE_NOT_FOUND` when\nrunning `dna mcp`.**\n\nThis means dependencies haven't been installed for `packages/dna` specifically. It\nonly happens on a local/dev clone of this monorepo, **not** on a real `npm install -g\n@calibrate-ds/dna` or `npx @calibrate-ds/dna` — `@modelcontextprotocol/sdk` is a\nregular `dependencies` entry in `packages/dna/package.json`, so a real npm install\npulls it in automatically. If you're seeing this, you don't need to worry about it as\na published-package user.\n\nIf you're working from a git clone, `packages/dna` has its own `package-lock.json`,\nseparate from any install step at the monorepo root — fix it with:\n\n```\ncd packages/dna\nnpm install\n```\n\n## Colour forms\n\nOne definition (`core/color-forms.mjs`) decides what counts as a colour, for extraction\n(`dna start`), enforcement (`dna check`), `dna resolve` and `dna allow color` alike.\n\n**Recognized**\n\n| Form | Examples |\n| --- | --- |\n| hex | `#fff` `#ffff` `#2e7d32` `#2e7d32cc` (3/4/6/8 digits — any other length is malformed) |\n| sRGB functions | `rgb()` `rgba()` `hsl()` `hsla()` `hwb()` |\n| modern functions | `oklch()` `oklab()` `lch()` `lab()` `color()` |\n\nA declared token in any of these forms enters `palette` with provenance like any other,\nand a raw literal in any of them (`color: oklch(0.7 0.1 150)`, `bg-[oklch(0.7_0.1_150)]`\n— Tailwind's `_` space encoding is decoded) is seen by `color-family-allowlist` /\n`prefer-token` / `prefer-token-class` like any other.\n\n**Normalisation rule.** For `oklch()`, `oklab()`, `lch()`, `lab()`, `hwb()` and\n`color()`, values are compared after: trim → lowercase → collapse internal whitespace\nruns to one space → no space just inside the parens → the alpha separator written as\nexactly ` / `. So `OKLCH( 0.70  0.10 150/50% )` and `oklch(0.70 0.10 150 / 50%)` are one\nvalue. **Nothing else is equated**: percentage and number forms (`oklch(70% …)` vs\n`oklch(0.7 …)`), `none` and `0`, and differing precision (`0.70` vs `0.7`) stay\n*different* values, because proving them equal needs colour maths this tool does not do.\nHex and `rgb()`/`hsl()` keep exactly the normalisation they always had (hex casing and\nshort-hex expansion; `hsl()` canonicalized to its hex, per the shadcn/Tailwind channel\nconvention).\n\n**What dna deliberately does NOT do**\n\n- **No colour-space conversion.** `oklch()`/`oklab()`/`lch()`/`lab()`/`color()` are\n  stored and compared as their normalised original string. Converting them to sRGB hex\n  needs gamut mapping, and an out-of-gamut colour has *no* exact hex — a clipped hex\n  presented as your token's value would be invented data.\n- **No cross-space equivalence.** `oklch(0.7 0.1 150)` and its visual hex twin are\n  different values to dna. `dna resolve '#2e7d32'` will not find an `oklch()` token.\n- **No colour family for these forms.** Family inference (`blue`, `green`, …) reads a\n  hex's channels; a non-sRGB value has none dna will claim, so such a token is\n  family-less — stated, never guessed. Consequences: a raw non-sRGB literal that is not\n  a palette value is still reported by `color-family-allowlist` (naming the literal, not\n  a family — exactly how a raw hex is reported today), and an *observed* non-sRGB\n  literal is never auto-named into `palette` (that name is derived from hex channels);\n  it is reported as an `unnamable-observed-color` skip instead, with the\n  `dna allow color '<value>' --as <name> --why …` command to adopt it deliberately. For\n  the same reason `dna allow color` requires `--as` for any non-hex value.\n- **`hwb()` is not converted either**, although it is plain sRGB and *could* be. One\n  rule for every colour function is easier to trust than \"some functions silently equal\n  a hex and others don't\", and converting it would add a second colour-maths path to\n  keep correct for no gain.\n- **Computed / context-dependent forms are not colours here.** `color-mix(...)`,\n  relative colour syntax (`oklch(from var(--brand) l c h)`), `light-dark(...)` and\n  anything containing an inner `var()` have no single value dna can state, so they are\n  never half-parsed: a declared token holding one is reported as `unclassified-value`\n  with its reason, and such a value in a **CSS declaration** produces no colour finding.\n  **Relative colour syntax splits in two, and the two halves point opposite ways.**\n  `bg-[oklch(from_var(--b)_l_c_h)]` (and the plain-CSS `color: oklch(from var(--b) l c h)`)\n  used to be read as a reference to the token `b`, exactly as `bg-[var(--b)]` is — which\n  was wrong about its *value*: the colour is computed **from** `--b`, it is not `--b`'s\n  colour. Its value is therefore never resolved, never a palette entry, and never an\n  `arbitrary-values` finding; it is reported as a `relative-color-syntax` **value-level\n  skip** (see *Coverage is accounted for, not assumed*, below). But `from var(--b)` does\n  **consume** `--b` — delete the token and the declaration breaks — so `ghost-tokens`\n  still counts it as a live use and will not report `--b` as dead, the same way it counts\n  `hsl(var(--b))`. Not resolvable, still alive: the two are separate questions, answered\n  separately. A malformed or unterminated call (`oklch(`), an **empty argument list**\n  (`oklch()`, `rgb()`, `hwb(  )` — a function name is not a colour), and an invalid hex\n  length (`#12`, `#1234567`) are parse failures routed to the same skip bucket — never\n  written to an artifact, never silently dropped.\n- **`dna resolve` keeps its exit-code contract.** A well-formed value that simply isn't\n  in your identity answers \"not a token\" at exit 0 — including `hsl(var(--primary))` and\n  any other colour function wrapping a `var()`, which is valid CSS that dna cannot\n  resolve through, and says so. Only genuinely malformed input (an invalid hex length,\n  an empty call) is a usage error at exit 1.\n\n### Behaviour changes for existing projects\n\nRecognising more colour forms also corrected four things that were wrong before. If you\nhave an identity from an earlier version, expect these on your next run:\n\n1. **Observed `rgb()`/`hsl()` usage colours are no longer auto-named.** A colour seen\n   only in usage was named from its hex channels; for a non-hex literal that produced a\n   hue out of `NaN` (a green could land in the palette as `red`). Such a value now\n   leaves the palette and is reported as an `unnamable-observed-color` skip instead —\n   and a class that used to get a `prefer-token-class` warning pointing at that\n   fabricated token now gets a `color-family-allowlist` error until you adopt the value\n   deliberately with `dna allow color '<value>' --as <name> --why …`.\n2. **Underscore-written arbitrary classes are decoded.** `bg-[rgb(0_0_0)]` and\n   `bg-[hsl(142_71%_29%)]` previously carried a value no browser would parse\n   (`rgb(0_0_0)`) and so could never match their own token; Tailwind's `_` space\n   encoding is now decoded before the value is read. Comma forms and hex are unchanged.\n3. **Shorthands no longer half-parse a `var()` colour.** Inside `border` /`box-shadow`,\n   `rgba(var(--x), .5)` used to be truncated at the inner `)` and reported as a colour\n   that was never written; it is now left alone.\n4. **`dna resolve` rejects invalid hex lengths.** `#12` and `#1234567` answered \"not a\n   token\" (exit 0); they are malformed, and are now `invalid` (exit 1).\n\n## Rules\n\n### How the `rules` config combines with the built-in defaults\n\n`rules` merges with the built-in rule table **per rule**. Every default rule is active\nunless your config names it — listing one rule does not disable the rest:\n\n```json\n\"rules\": {\n  \"color-family-allowlist\": { \"severity\": \"error\", \"allowedFamilies\": [\"green\"] }\n}\n```\n\nHere `color-family-allowlist` takes your settings; `arbitrary-values`, `ghost-tokens`,\n`off-grid-spacing`, `prefer-token-class`, `builtin-type-size` and `prefer-scale-step` keep\ntheir built-in defaults and run. Each rule you *do* name is merged **shallowly** on top of\nits default, so a partial entry keeps the fields you left out:\n\n```json\n\"rules\": { \"ghost-tokens\": { \"allow\": { \"--legacy-ink\": \"kept for the old theme\" } } }\n```\n\nkeeps `ghost-tokens`' default `severity` (`warn`) and `severityReason`. A `severity` or\n`severityReason` you write always wins over the default's.\n\n**To turn a rule off, say so explicitly** — omission no longer disables anything:\n\n```json\n\"rules\": { \"prefer-token-class\": { \"severity\": \"off\" } }\n```\n\nEvery other top-level config key (`includePaths`, `tokenSources`, `scale`, `resolvers`, …)\nstill *replaces* the default outright. `rules` is the only key that merges.\n\n**`resolvers`** (default `'auto'`) picks which parser resolves a matched file to the\nnormalized IR. `'auto'` (the default) tries each registered resolver's own file-type\ntest (`jsts` for `.js`/`.jsx`/`.mjs`/`.cjs`/`.ts`/`.tsx`, `postcss` for\n`.css`/`.scss`/`.less`/`.pcss`) and uses whichever matches. Set it to an object —\n`{ \"<file>\": \"<resolverName>\", \"default\": \"<resolverName>\" }` — to force a specific\nresolver per file or as a fallback, bypassing the auto-detect test entirely\n(`core/lint.mjs` L32; `resolverFor` in `core/resolvers.mjs` L321-323).\n\n**Upgrading from 0.2.17 or earlier.** A `rules` key used to replace the whole default\ntable, so every rule you had not re-listed was silently off — including rules added in\nlater releases, which therefore never ran for you. The first `dna check` after upgrading\nprints one block naming the built-in default rules that are running and that your config\ndoes not mention, with each rule's severity, why it carries that severity, and how to turn\nit off. The same text is on the `dna check` result object and on MCP `dna_check` as\n`rulesUpgradeNotice`. Some defaults are `error` severity, so a commit hook or CI job that\nwas green can go red after the upgrade — the notice tells you which rule and why. See the\nCHANGELOG's migration note for the release-level summary.\n\nThe notice states the cause **conditionally** (\"if you upgraded from 0.2.17 or earlier,\nthese were previously off\"), because the same block also announces a default rule added in\na later release, which was never disabled by anything — it simply did not exist yet.\n\nIt is shown **once per repository**, not once per machine. The record is a `rules-merge`\nline in `.dna/decisions.jsonl`, which is committed (see \"What to commit\"), so you, your\nteammates and CI see the notice exactly once between you:\n\n```json\n{\"ts\":\"…\",\"type\":\"rules-merge\",\"scope\":\"arbitrary-values,builtin-type-size,ghost-tokens,off-grid-spacing,prefer-scale-step,prefer-token-class\",\"reason\":\"…\"}\n```\n\n`scope` is every built-in default rule that was **running** on that run — not just the ones\nannounced — or `none` if no default rule runs at all. Recording what runs is what makes\nordinary config edits quiet: adding a `rules` key to a config that never had one, or\ntrimming a config that listed the whole table, changes nothing about which rules run, so\nnothing is announced. Tracking is per rule, so a default added in a future release is not\ncovered by an older marker and is announced on its own.\n\nWhat this guarantees, precisely: **as long as `.dna/decisions.jsonl` is committed**, every\nclone and CI job agrees on what has already been seen, and no checkout is told about an\nupgrade it did not go through. If you git-ignore the ledger against the advice in \"What to\ncommit\", the fallback is `.dna/state.json`, which is local — the notice then appears once\nper machine instead. A project checked for the first time ever stays silent and records the\nmarker on that run.\n\nOne more visible change on a project's first run: `typography-role` is now part of the\ndefault table, so a first run records one extra `severity` decision for it (at `off`)\ncompared with earlier releases.\n\n`dna doctor` has a `rules` line listing every rule that is off and whether it is off\nbecause *your config* said so or because that is its *default*, and it warns about any\n`rules` key that matches no real rule (a typo does nothing, silently, otherwise).\n\n- **`typography-role`** (**off** by default) flags a type *token* used outside the files\n  that **are** your type primitives — it enforces role (`<SectionTitle>`), not just value.\n  It ships off because it needs `allowFiles` to mean anything: with an empty allowlist\n  every type-token use anywhere would flag. Name your primitives, then raise it:\n  ```json\n  \"typography-role\": { \"severity\": \"error\", \"allowFiles\": [\"src/components/typography\"] }\n  ```\n  `builtin-type-size` shares the same `allowFiles` list (see below).\n\n- **`off-grid-spacing`** checks **grid divisibility, not scale membership**, by\n  default: a value that's a multiple of the configured grid (`scale`, default `4`)\n  passes even if it was never one of the actual declared steps — e.g. at `grid: 4`,\n  `p-11` (44px) passes because `44 % 4 === 0`, even though 44 isn't in a scale like\n  `[4, 8, 12, 16, 24, 32]`. This is deliberate: a literal-membership check false-\n  positived on legitimate section spacing (`py-8`, `py-12`) that wasn't in an\n  initially-declared scale, so grid divisibility is the permissive default for every\n  existing user.\n  Opt in to stricter checking with `mode: \"scale\"`. In this mode, a value must be an\n  exact member of a declared scale array — `p-11` (44px, on-grid but not a real step)\n  is flagged; `p-8` (32px, in the array) is not. `mode` unset, or `\"grid\"`, keeps the\n  default divisibility-only behaviour unchanged.\n\n  The declared array can come from two places, most specific wins:\n  1. an explicit override in the rule config itself:\n     ```json\n     \"off-grid-spacing\": { \"severity\": \"error\", \"mode\": \"scale\", \"scale\": [4, 8, 12, 16, 24, 32] }\n     ```\n  2. failing that, `.dna/identity.yaml`'s own `scales.spacingScale` — written\n     automatically by `dna start` when a project's own `tailwind.config.*` declares a\n     real `theme.spacing`/`extend.spacing` (the project's genuine declared scale, not a\n     guess), or hand-authored the same way. Absent from the identity for every project\n     that hasn't declared one — no behaviour change for them.\n\n  If `mode: \"scale\"` is set but neither source resolves an array, the rule falls back\n  to the grid check rather than silently going permissive or over-flagging.\n\n- **`builtin-type-size`** (warn by default) flags a **built-in Tailwind font-size\n  utility** — `text-xs`/`text-sm`/`text-base`/`text-lg`/`text-xl`/`text-2xl` … `text-9xl`,\n  variant-prefixed forms (`md:text-lg`) included — used in a project whose\n  `.dna/identity.yaml` declares a `scales.type`. It's the same bypass `text-[14px]`\n  already gets flagged for, in the one form no rule could previously see. The message\n  names the class, the px **Tailwind renders that name at by default**, and — when that\n  px is on your scale — the identity token that renders the same size:\n\n  ```\n  text-sm (Tailwind default 14px) bypasses your type scale — use the \"body\" type token instead\n  ```\n\n  The px is always labelled as Tailwind's *default*, never asserted as what your app\n  renders: `dna` deliberately does not read your `tailwind.config.*` `theme.fontSize`, so\n  a project that overrode the defaults renders something else and is told the number's\n  proven","readmeFilename":"README.md"}