{"_id":"@aquex/stage1","_rev":"11-1cce6dd2df9c5db5dce64c6766d7fb39","name":"@aquex/stage1","dist-tags":{"latest":"0.7.0"},"versions":{"0.1.0":{"name":"@aquex/stage1","version":"0.1.0","author":{"name":"System Systems LLC"},"license":"Apache-2.0","_id":"@aquex/stage1@0.1.0","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"homepage":"https://github.com/kneelinghorse/Stage1#readme","bugs":{"url":"https://github.com/kneelinghorse/Stage1/issues"},"bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"dist":{"shasum":"99826ff81c5cb0432f7e496b2bccf95acdf814f9","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.1.0.tgz","fileCount":14,"integrity":"sha512-5knOVd2qg9++uwJrAxxonU3XcACdVWYzhkHklGJzY0s7+FheTWCRWzkRL2s9hGEvHvH5lWqx42hjVe+kLOOpVw==","signatures":[{"sig":"MEUCIFoOsjvTulbwNmnBOYdqcMjhxIezkV1pAfazJ6iJ+slEAiEAsqYyHKe0LnCC5JWL7xyxy+LtJRYo3HRnIMfMJssaY9E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3305602},"type":"module","_from":"file:/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-QrmeXX/reviewed.tgz","engines":{"node":"^22.15.0 || ^24.0.0"},"exports":{},"scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"_resolved":"/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-QrmeXX/reviewed.tgz","_integrity":"sha512-5knOVd2qg9++uwJrAxxonU3XcACdVWYzhkHklGJzY0s7+FheTWCRWzkRL2s9hGEvHvH5lWqx42hjVe+kLOOpVw==","repository":{"url":"git+https://github.com/kneelinghorse/Stage1.git","type":"git","directory":"packages/stage1"},"_npmVersion":"11.5.1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"_nodeVersion":"24.6.0","dependencies":{"uuid":"13.0.0","commander":"14.0.0","lighthouse":"12.8.2","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","puppeteer-core":"24.43.1","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.25.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/stage1_0.1.0_1790309773973_0.3154453615441437","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aquex/stage1","version":"0.2.0","author":{"name":"System Systems LLC"},"license":"Apache-2.0","_id":"@aquex/stage1@0.2.0","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"dist":{"shasum":"1132256e8a7d7420cb7cfe616ce97e1640e77f9a","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.2.0.tgz","fileCount":14,"integrity":"sha512-gxGC2XW3jOPZeCjw74kI+m2e9GY4eQmYBYBg6xitadI8u58MWRrKh7LMai/NBIQz18A967GhI44Pod5QrmtJBg==","signatures":[{"sig":"MEUCIFfSQQl3de1fHfgm89szkcel1DXfUVdoOdRJXLWRioWRAiEAwqyRKwCNkHMtdfSeP0KtcSDAK7MIBU5AvvJq/r48UIU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIAtIaIWcVDer9QrGXpEmhBtqwk+XnpcEsLsatIYXtSO2AiALglpfHgbIlrv66FHGaDXYIpUpEo8WdKkPuplAVKtWJg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3623439},"type":"module","_from":"file:/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-cHLSL3/reviewed.tgz","engines":{"node":"^22.15.0 || ^24.0.0"},"exports":{},"scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"_resolved":"/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-cHLSL3/reviewed.tgz","_integrity":"sha512-gxGC2XW3jOPZeCjw74kI+m2e9GY4eQmYBYBg6xitadI8u58MWRrKh7LMai/NBIQz18A967GhI44Pod5QrmtJBg==","_npmVersion":"11.5.1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"_nodeVersion":"24.6.0","dependencies":{"uuid":"13.0.0","axios":"1.11.0","chalk":"5.6.2","graphql":"16.12.0","p-limit":"7.1.1","postcss":"8.5.28","fs-extra":"11.3.1","commander":"14.0.0","lighthouse":"12.8.2","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","postcss-scss":"4.0.9","puppeteer-core":"24.43.1","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.25.1","@apidevtools/swagger-parser":"12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/stage1_0.2.0_1790378465372_0.0499060280004302","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aquex/stage1","version":"0.3.0","author":{"name":"System Systems LLC"},"license":"Apache-2.0","_id":"@aquex/stage1@0.3.0","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"dist":{"shasum":"7308fe0b87f3de4d70f5559119c0980dcb011c5e","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.3.0.tgz","fileCount":14,"integrity":"sha512-EPzgHDCYw/nCcV+qzJ9/EWfCZPiWbLyQHGItcPgfNZ+FUbmHD3z++reML7WBadolfn0GRGr4tAmXTA71LomFJw==","signatures":[{"sig":"MEYCIQClUdzg9dsrO1iBAZGEJ0123JesQ6Nn/gV+Wtc2fg8OhAIhAPf4ypJsSiuH9859KtzVO2SBp5VeqVHYkimpuJSbpLA5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIF0+z4Faw2HltTBO4Y1End9mzEV5TBglIrW539IQkfRQAiEAg8EtBxFWAlJQ/9k1d/s7yk2xnIW9ukT0O+G4nVed/lw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3700579},"type":"module","_from":"file:/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-UwtL8c/reviewed.tgz","engines":{"node":"^22.15.0 || ^24.0.0"},"exports":{},"scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"_resolved":"/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-UwtL8c/reviewed.tgz","_integrity":"sha512-EPzgHDCYw/nCcV+qzJ9/EWfCZPiWbLyQHGItcPgfNZ+FUbmHD3z++reML7WBadolfn0GRGr4tAmXTA71LomFJw==","_npmVersion":"11.5.1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"_nodeVersion":"24.6.0","dependencies":{"uuid":"13.0.0","yaml":"2.8.1","axios":"1.11.0","chalk":"5.6.2","graphql":"16.12.0","p-limit":"7.1.1","postcss":"8.5.28","fs-extra":"11.3.1","commander":"14.0.0","lighthouse":"12.8.2","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","postcss-scss":"4.0.9","puppeteer-core":"24.43.1","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.25.1","@apidevtools/swagger-parser":"12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/stage1_0.3.0_1790425163973_0.8127779212674824","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@aquex/stage1","version":"0.3.1","author":{"name":"System Systems LLC"},"license":"Apache-2.0","_id":"@aquex/stage1@0.3.1","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"dist":{"shasum":"5f413dd34970567aeb01b52b2cc24680a4156f01","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.3.1.tgz","fileCount":14,"integrity":"sha512-JJjo+KcAqJ1hDwt693toa2oyPhI0QbDoSfErmLCaMoqTc2lTWEtw9jtUeWvzXbgUj7iSEVlrnd2uHETojA2Etw==","signatures":[{"sig":"MEQCIDUFR0oZ6rxwjqlcd6Lk8xdTtQW5rvv1iXuBTy5Wbv2pAiBqyV8C9icZhhw/8tmSEDgs1W4vH16cndyQgeHMYjaaxA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIGxMHJAhyKtILbjVg5UZK8462MEPjmEUSRgoqBWQL9d5AiEA1HQiCGYJkFguBYc8v6dfdneW0SInVeOggl2jk2ExpZg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3704697},"type":"module","_from":"file:/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-43GJNw/reviewed.tgz","engines":{"node":"^22.15.0 || ^24.0.0"},"exports":{},"scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"_resolved":"/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-43GJNw/reviewed.tgz","_integrity":"sha512-JJjo+KcAqJ1hDwt693toa2oyPhI0QbDoSfErmLCaMoqTc2lTWEtw9jtUeWvzXbgUj7iSEVlrnd2uHETojA2Etw==","deprecated":"0.3.1 can store a credential embedded in a single-site target URL (http://user:pass@host) in run records and exports. Upgrade to 0.3.2, which refuses such URLs: npm install --global @aquex/stage1@0.3.2","_npmVersion":"11.5.1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"_nodeVersion":"24.6.0","dependencies":{"uuid":"13.0.0","yaml":"2.8.1","axios":"1.11.0","chalk":"5.6.2","graphql":"16.12.0","p-limit":"7.1.1","postcss":"8.5.28","fs-extra":"11.3.1","commander":"14.0.0","lighthouse":"12.8.2","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","postcss-scss":"4.0.9","puppeteer-core":"24.43.1","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.25.1","@apidevtools/swagger-parser":"12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/stage1_0.3.1_1790519902400_0.23275599521332224","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@aquex/stage1","version":"0.3.2","author":{"name":"System Systems LLC"},"license":"Apache-2.0","_id":"@aquex/stage1@0.3.2","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"bugs":{"email":"stage1@aquex.ai"},"bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"dist":{"shasum":"8cf43da89b0d9ce4770d1760a00e940a11e92e0f","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.3.2.tgz","fileCount":14,"integrity":"sha512-nsz34iXC6lSmRtj8oUN+sibg0Zm+FId4azpulguDfR8xo1EgJ6J39/MLyUMWrkoLiMgB879xWaw3xNJQG96Xjg==","signatures":[{"sig":"MEUCID9nO+Cjgu2QLw0rr5EnOfzEUHom6oKDiAKABTYmdE+VAiEApXy2vjRfy5j1Uwr7qwY5fWqqGKNHel1LNf4ZUfBWtf8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDBOWH0Tu1NOSyQRxreW+mKon1Z+Px6r/Mfkj+KkgjSjAIgGbHpjCeNOcpiCLOY2HSTjgsJaoNcSQaX/SUaf5xpdbY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3716168},"type":"module","_from":"file:/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-IUWs15/reviewed.tgz","engines":{"node":"^22.15.0 || ^24.0.0"},"exports":{},"scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"_resolved":"/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-IUWs15/reviewed.tgz","_integrity":"sha512-nsz34iXC6lSmRtj8oUN+sibg0Zm+FId4azpulguDfR8xo1EgJ6J39/MLyUMWrkoLiMgB879xWaw3xNJQG96Xjg==","_npmVersion":"11.5.1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"_nodeVersion":"24.6.0","dependencies":{"uuid":"13.0.2","yaml":"2.8.4","axios":"1.20.0","chalk":"5.6.2","graphql":"16.12.0","p-limit":"7.1.1","postcss":"8.5.28","fs-extra":"11.3.1","commander":"14.0.0","lighthouse":"12.8.2","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","postcss-scss":"4.0.9","puppeteer-core":"24.43.1","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.26.0","@apidevtools/swagger-parser":"12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/stage1_0.3.2_1790652086922_0.8331025165922272","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@aquex/stage1","version":"0.4.0","author":{"name":"System Systems LLC"},"license":"Apache-2.0","_id":"@aquex/stage1@0.4.0","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"bugs":{"email":"stage1@aquex.ai"},"bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"dist":{"shasum":"4b6f2a128d6c104e30f0f2a07fcf31c2b1b23d08","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.4.0.tgz","fileCount":14,"integrity":"sha512-Ih5PcyDFQ1ClHTDWeFr2N0XfUMRBuxGWfqxPgWQftVudEZxzuwMtLWAiqgI2D5wgdrSr6TtSXOY3eb9hKDHwYg==","signatures":[{"sig":"MEYCIQDt3rqU/Qw7sQGctGc0Lw1WIQwQ2g97eUjw/X9xr0u1IwIhAL8BqVibUnsHjH55ePyjt2O8o1PSdvrhVMkqQ4c/w14+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCEMPucIn4VqXuTssJaFPg94ZJ5Q93OxAUE/hsogK7sTQIhAN9nkabPov69/IEOwPvgiiKz5YIwpVEKtDBFd+GD3wMS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3793556},"type":"module","_from":"file:/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-Ej7hdk/reviewed.tgz","engines":{"node":"^22.15.0 || ^24.0.0"},"exports":{},"scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"_resolved":"/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-Ej7hdk/reviewed.tgz","_integrity":"sha512-Ih5PcyDFQ1ClHTDWeFr2N0XfUMRBuxGWfqxPgWQftVudEZxzuwMtLWAiqgI2D5wgdrSr6TtSXOY3eb9hKDHwYg==","_npmVersion":"11.5.1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"_nodeVersion":"24.6.0","dependencies":{"uuid":"13.0.2","yaml":"2.8.4","axios":"1.20.0","chalk":"5.6.2","graphql":"16.12.0","p-limit":"7.1.1","postcss":"8.5.28","fs-extra":"11.3.1","commander":"14.0.0","lighthouse":"12.8.2","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","postcss-scss":"4.0.9","puppeteer-core":"24.43.1","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.26.0","@apidevtools/swagger-parser":"12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/stage1_0.4.0_1790907136632_0.35962785549332255","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@aquex/stage1","version":"0.5.0","author":{"name":"System Systems LLC"},"license":"Apache-2.0","_id":"@aquex/stage1@0.5.0","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"bugs":{"email":"stage1@aquex.ai"},"bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"dist":{"shasum":"01e3a5a3b0cf2bcc2c002db0e2f7a24c5fdeca4f","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.5.0.tgz","fileCount":14,"integrity":"sha512-FmaMNh9frY2Z/RC8Tsuw/1KPswkFYkH1VqOxtiVeo4Jei2v+RpsKKrC3lmqaxgbkzisecaoubAzw3LqMVDR6Pg==","signatures":[{"sig":"MEQCIDj/6i7SXGpR3nZ5ErcxT4Vi3ggEO/jCrz9gEzwWNL5fAiBklpZSOUmaQu4j2OaoI7APZQ/4d/bV/km00uASx7a4Pw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIBBmSoa2WXTFZPOpnaXLh/HqBBEZt0gDpzreyRJboQApAiBkNk45qPtLfJCXuK1N1VnIadqR+Q1xuYITQemb0/WarQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3498551},"type":"module","_from":"file:/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-EoNslp/reviewed.tgz","engines":{"node":"^22.19.0 || ^24.0.0"},"exports":{},"scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"_resolved":"/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-EoNslp/reviewed.tgz","_integrity":"sha512-FmaMNh9frY2Z/RC8Tsuw/1KPswkFYkH1VqOxtiVeo4Jei2v+RpsKKrC3lmqaxgbkzisecaoubAzw3LqMVDR6Pg==","_npmVersion":"11.5.1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"_nodeVersion":"24.6.0","dependencies":{"uuid":"13.0.2","yaml":"2.8.4","axios":"1.20.0","chalk":"5.6.2","culori":"4.0.2","graphql":"16.12.0","p-limit":"7.1.1","postcss":"8.5.28","fs-extra":"11.3.1","commander":"14.0.0","lighthouse":"13.5.0","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","postcss-scss":"4.0.9","puppeteer-core":"25.12.0","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.31.0","@apidevtools/swagger-parser":"12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/stage1_0.5.0_1791375063540_0.7435843532969009","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@aquex/stage1","version":"0.5.1","author":{"name":"System Systems LLC"},"license":"Apache-2.0","_id":"@aquex/stage1@0.5.1","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"homepage":"https://aquex.ai/products/stage1","bugs":{"email":"stage1@aquex.ai"},"bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"dist":{"shasum":"d42a8235cb206d5579bec136c8e6969d40bbee75","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.5.1.tgz","fileCount":14,"integrity":"sha512-NeEIEQU6tsG4B3eAUtil2DD07lCnOGKKYBWkGB+hX4i3auZgw2k1XrX8Aojc3Lc9MSlHYwLXlcfAd+lz8cNmPw==","signatures":[{"sig":"MEUCIQC3eExCOod/bxE9/vlmN2YXfIMyGlLteD0siNe/UHGpZAIgJr3QUxZ3pa3rYVksOaoHEVH639qjX1yrrAmhHEs/OdU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIA2gVb0JQOGv2mBnsutHAfq4+4PFiIO0JJxqws2PowICAiEAw7Obeyq6qvjzzdJexEmX2gjdMI0H4YSWaEQEi7y66Qc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3500040},"type":"module","_from":"file:/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-wKzpzI/reviewed.tgz","engines":{"node":"^22.19.0 || ^24.0.0"},"exports":{},"mcpName":"ai.aquex/stage1","scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"_resolved":"/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-wKzpzI/reviewed.tgz","_integrity":"sha512-NeEIEQU6tsG4B3eAUtil2DD07lCnOGKKYBWkGB+hX4i3auZgw2k1XrX8Aojc3Lc9MSlHYwLXlcfAd+lz8cNmPw==","_npmVersion":"11.5.1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"_nodeVersion":"24.6.0","dependencies":{"uuid":"13.0.2","yaml":"2.8.4","axios":"1.20.0","chalk":"5.6.2","culori":"4.0.2","graphql":"16.12.0","p-limit":"7.1.1","postcss":"8.5.28","fs-extra":"11.3.1","commander":"14.0.0","lighthouse":"13.5.0","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","postcss-scss":"4.0.9","puppeteer-core":"25.12.0","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.31.0","@apidevtools/swagger-parser":"12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/stage1_0.5.1_1791426305912_0.6133539815558731","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@aquex/stage1","version":"0.6.0","author":{"name":"System Systems LLC"},"license":"Apache-2.0","_id":"@aquex/stage1@0.6.0","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"homepage":"https://aquex.ai/products/stage1","bugs":{"email":"stage1@aquex.ai"},"bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"dist":{"shasum":"2a6d21b6f24d36220636e536aa255e9072a52241","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.6.0.tgz","fileCount":14,"integrity":"sha512-XjfltE3zP5heODQfBqEvJ0yM8wEys34S7U4TIxSGykuRRpxErcbCSGqPWmmlerSRUIDT7nNRgvzPPn3aTSZrhA==","signatures":[{"sig":"MEUCIQCcxTpk0aUip3g/YKFyQKJYk+QSThs/Ys8aHavPuldI8gIgSkv/eIsZO9VGUTQFUNeB0LXxz2M19iZe7kH19rvScWA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQC5HGSaidKm9dCc1jd20p9QzfEg6XOMQFgysJN0+bc1cAIgWw9Soa4F/jqqC18DMrDEfOrtmOuNyvkGZhIozLf28pY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3587051},"type":"module","_from":"file:/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-105jy3/reviewed.tgz","engines":{"node":"^22.19.0 || ^24.0.0"},"exports":{},"mcpName":"ai.aquex/stage1","scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"_resolved":"/var/folders/gd/rty3217130vdbr9_q713nvg80000gn/T/stage1-reviewed-release-105jy3/reviewed.tgz","_integrity":"sha512-XjfltE3zP5heODQfBqEvJ0yM8wEys34S7U4TIxSGykuRRpxErcbCSGqPWmmlerSRUIDT7nNRgvzPPn3aTSZrhA==","_npmVersion":"11.5.1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"_nodeVersion":"24.6.0","dependencies":{"uuid":"13.0.2","yaml":"2.8.4","axios":"1.20.0","chalk":"5.6.2","culori":"4.0.2","graphql":"16.12.0","p-limit":"7.1.1","postcss":"8.5.28","fs-extra":"11.3.1","commander":"14.0.0","lighthouse":"13.5.0","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","postcss-scss":"4.0.9","puppeteer-core":"25.12.0","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.31.0","@apidevtools/swagger-parser":"12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/stage1_0.6.0_1791464671391_0.19008672618587785","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"_id":"@aquex/stage1@0.7.0","bin":{"stage1":"dist/cli.js","stage1-mcp":"dist/mcp.js"},"bugs":{"email":"stage1@aquex.ai"},"dist":{"shasum":"a5c10c44976708def1fecaaf074b1fca9cb92ae1","tarball":"https://registry.npmjs.org/@aquex/stage1/-/stage1-0.7.0.tgz","fileCount":14,"integrity":"sha512-/Ht123bJsWINpiObGv7ZXyVPbo7+GeqxkZxNozWYfm+IQ/EdVJsdOSQpiwrWPU2WER0xZD/ctfeYaAMwM5w4Bg==","signatures":[{"sig":"MEUCIHqK1+s2e4QfBc4tW0NM5rtTG9o9fLl83Sph+++33/3yAiEA+DNdyLsqFETCU+quyeTMXp3u+pVtQ9cInKYkqv2PTUs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBB56RURPtlIkQzqBsUd4EAz8WKb0mmWaep7JY6GfSRFAiEAm81AJkLYW/c2jVXiLa/FLoYo+Kw+3Y1dOXW21P3pW74="}],"unpackedSize":3683735},"name":"@aquex/stage1","type":"module","_from":"file:/var/folders/qx/ss3wnyln2034s2hbzlt2pxd00000gn/T/stage1-reviewed-release-h0aB2e/reviewed.tgz","author":{"name":"System Systems LLC"},"engines":{"node":"^22.19.0 || ^24.0.0"},"exports":{},"license":"Apache-2.0","mcpName":"ai.aquex/stage1","scripts":{"test":"node --test test/*.test.mjs","build":"node scripts/build.mjs","pack:review":"node scripts/pack.mjs","prepublishOnly":"node -e \"throw new Error('Publication requires release candidate approval and the release workflow')\""},"version":"0.7.0","_npmUser":{"name":"kneelinghorse","email":"derekn@shout.net"},"homepage":"https://aquex.ai/products/stage1","_resolved":"/var/folders/qx/ss3wnyln2034s2hbzlt2pxd00000gn/T/stage1-reviewed-release-h0aB2e/reviewed.tgz","_integrity":"sha512-/Ht123bJsWINpiObGv7ZXyVPbo7+GeqxkZxNozWYfm+IQ/EdVJsdOSQpiwrWPU2WER0xZD/ctfeYaAMwM5w4Bg==","_npmVersion":"11.19.0","description":"Stage1 Inspector — local website capture, evidence views and design comparison","directories":{},"maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"_nodeVersion":"24.21.0","dependencies":{"uuid":"13.0.2","yaml":"2.8.4","axios":"1.20.0","chalk":"5.6.2","culori":"4.0.2","graphql":"16.12.0","p-limit":"7.1.1","postcss":"8.5.28","fs-extra":"11.3.1","commander":"14.0.0","lighthouse":"13.5.0","patchright":"1.61.1","playwright":"1.57.0","kiwi-schema":"0.5.0","tldts-icann":"6.1.86","postcss-scss":"4.0.9","puppeteer-core":"25.13.0","chrome-launcher":"1.2.1","node-html-parser":"7.0.1","@axe-core/playwright":"4.11.0","@modelcontextprotocol/sdk":"1.32.2","@apidevtools/swagger-parser":"12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.5","esbuild":"^0.25.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/stage1_0.7.0_1793631639272_0.30886312479144773"}}},"time":{"created":"2026-09-25T04:16:13.749Z","modified":"2026-11-02T15:00:39.632Z","0.1.0":"2026-09-25T04:16:14.159Z","0.2.0":"2026-09-25T23:21:05.472Z","0.3.0":"2026-09-26T12:19:24.075Z","0.3.1":"2026-09-27T14:38:22.520Z","0.3.2":"2026-09-29T03:21:27.034Z","0.4.0":"2026-10-02T02:12:16.731Z","0.5.0":"2026-10-07T12:11:03.689Z","0.5.1":"2026-10-08T02:25:06.028Z","0.6.0":"2026-10-08T13:04:31.512Z","0.7.0":"2026-11-02T15:00:39.431Z"},"bugs":{"email":"stage1@aquex.ai"},"author":{"name":"System Systems LLC"},"license":"Apache-2.0","homepage":"https://aquex.ai/products/stage1","description":"Stage1 Inspector — local website capture, evidence views and design comparison","maintainers":[{"name":"kneelinghorse","email":"derekn@shout.net"}],"readme":"# Stage1 Inspector\n\nStage1 shows what shipped and compares it with declared design intent. Capture a website locally, inspect its evidence in a browser, and compare the measured values with a local Figma kit, CSS/SCSS declarations or JSON tokens. Each comparison names its rule, explains non-matches and links findings to captured evidence.\n\nStage1 is free, Apache-2.0 software with the `stage1` CLI, `stage1-mcp` stdio server and a local UI. It reports measurements, coverage and missing evidence. Newly produced Stage1 records contain no Stage1-made quality score or confidence rating; drift severity stays in JSON for the receiving object contract and is not shown in Stage1 views. Tool-native values remain in their raw reports. See LICENSE, NOTICE and THIRD-PARTY-NOTICES.md.\n\nOODS Foundry declares what things are; Stage1 shows what shipped and checks it against what was declared. Use Stage1's own views for 0.5.x records until OODS Foundry admits their new artifact versions. A joint demonstration must use versions admitted by both products.\n\nThis guide describes Stage1 Inspector 0.7.0. No supported JavaScript library API is exported.\n\n[Install](#install-and-upgrade) · [Quick start](#capture-view-export) · [Capture options](#capture-limits-and-options) · [Suites](#multi-site-suites-and-discovery) · [Guided sessions](#guided-sessions) · [Design comparison](#local-fig-comparison) · [Baselines](#baselines-and-stage1-diff) · [Team rules](#your-teams-rules-and-stage1-check) · [CI](#run-the-check-in-github-actions) · [MCP](#mcp-clients) · [Troubleshooting](#troubleshooting) · [API inspection](#api-declarations) · [Source inspection](#local-source-repository)\n\n## Install and upgrade\n\nUse a maintained Node 22 release at least 22.19.0, or Node 24 at least 24.0.0. Node 20, 23 and 25 are outside this release contract. The release qualification scope is Ubuntu 22.04/24.04 x64, macOS 14 ARM64 and macOS 15 Intel. Windows (including Windows 11 x64) and macOS 14 Intel remain unverified. Other OS/architecture combinations are outside this verified scope.\n\n```sh\nnpm install --global @aquex/stage1@0.7.0\nstage1 --version\nstage1 --help\n```\n\nUpgrade by installing an explicit new version with the same command. Keep existing run directories: installation does not migrate or rewrite them. Direct runtime dependencies are pinned; their registry-resolved transitive dependencies can change between installations.\n\nLocal capture uses installed Chrome, or the package's pinned Chromium fallback. If Chrome is unavailable:\n\n```sh\nstage1 browser setup\n```\n\nThis downloads browser binaries from the automation runtime's distribution service; it needs internet access and disk space. A measured macOS arm64 installation downloaded about 266 MiB and occupied about 539 MiB for Chromium, its headless shell and FFmpeg, separately from npm dependencies. Sizes vary by platform/revision; allow additional space for downloads and run evidence. Linux also needs the browser's system libraries. Setup uses the installed Patchright revision, not a separately downloaded latest npm tool.\n\n## Capture, view, export\n\nSubstitute a site you control. Commands below use paths relative to your current directory. Capture prints the run directory; replace `RUN_DIR` and `RUN_ID` with that directory and its manifest run ID. Quote paths that contain spaces. For a local development server, include the scheme (for example, `http://localhost:3000`). Keep usernames and passwords out of URLs; use `--auth` with a local browser storage-state file for signed-in captures.\n\n```sh\nstage1 inspect app --url https://example.com --out ./runs --max-pages 5 --crawl-depth 1\nstage1 view RUN_DIR --port 0\n```\n\nThe second command prints a loopback URL and stays running until Ctrl-C. View reads the source run. Routes expose capture coverage, page evidence, accessibility, performance and comparison when present. Performance covers at most five pages. Responsive width replay requires `--include responsive.widths`; it is not part of the default capture. Run-side token records show observed values and site-declared custom-property names, without invented design roles. Missing or failed measurements are disclosed; absence is not zero.\n\nReview the run's contents and rights before approving a local export:\n\n```sh\nstage1 view RUN_DIR --export ./share-run --approve-sharing RUN_ID\n```\n\nOpen `share-run/index.html` directly, including via `file://`. The destination must be fresh and outside the source. This writes locally; it does not upload, host or deploy.\n\n`--approve-sharing` declares that you control this run and approve its subject and selected comparison for sharing. The receipt binds your declaration to the run and optional analysis manifest digests. It is an operator declaration, not independent proof of rights. Another run ID, changed manifests, unsafe paths and existing destinations are refused.\n\nAuthenticated captures also require `--approve-authenticated-sharing RUN_ID`. This additional declaration covers the authenticated contents, including any selected comparison. Operator-controlled guided records require it too, since a person can sign in during capture.\n\nThe report is an inline view model, with selected linked files: screenshots, summarized accessibility evidence and available visual-system drill-downs. Comparison operand files are included only when findings link to them. This is not a copy of every run artifact. Computed-style evidence, raw CSS-rule evidence, crawl and network records, `drift_report.json`, `signal_places.json`, captured HTML, HARs, raw Lighthouse reports, offload records and credentials are not exported as files.\n\nLinked evidence is checked against source attestations; missing or changed evidence is withheld. URL query values are removed from JSON copies; source and exported digests are recorded separately. Screenshots can still contain visible personal or confidential information. Original run bytes remain unchanged.\n\n### Which design systems a site runs\n\nEvery app capture (and suite target) writes `design_systems.json` from the evidence it kept, with no extra browsing. It\nnames the design systems and UI libraries the site's own evidence identifies, from a first-party list of ten: USWDS,\nGOV.UK Frontend, Tailwind CSS, shadcn/ui, Radix, Base UI, React Aria, Bootstrap, Material UI and Carbon. No third-party\nsignature database ships.\n\nA system is identified by:\n\n- three or more distinct names from its own list on a page (component classes, or shadcn's `data-slot` part names);\n- its attribute or custom-property namespace (`data-radix-*`, `--tw-*`), or its custom elements;\n- a request path that names it, an inline script that names it (`uswdsPresent`), or a source-map module.\n\nA version is given only where a stylesheet or script banner (`/*! … */` or `@license`) names the system with a full\nx.y.z, or where the package path does. Visible text, links and query values never become a version. Version text that\nthe pages show outside the main content, at the same place on at least 90% of pages, is listed on its own line and\nattached to no system.\n\nContent a third party's script inserted is reported apart from the site's own. A page whose insertion record did not\njoin is counted with its pages stated, never treated as first party. A system no rule matched is \"not identified\",\nnever absent, and nothing is scored.\n\nThe Overview's \"What the site declares\" card prints each system's statement word for word. `stage1_get_artifact`\nreturns the file with its attestation.\n\nOn designsystem.digital.gov's 0.7.0 run of record, USWDS is identified by `uswds.min.js` and `usa-banner.js.mjs` on 40\nof 40 pages, 1,945 elements with USWDS component classes and the inline `uswdsPresent` check. The site's own 4\nstylesheets and scripts were read, and none carries a banner naming it, so no version is given. The navigation's\n\"Download v3.14.0\" is shown on its own line. Inside the feedback widget that touchpoints.app.cloud.gov inserts, a\nbanner declares USWDS 2.9.0 on 39 of 39 pages, both in the `<style>` the widget inserts and in its script.\n\n## Capture limits and options\n\n`inspect app` defaults to depth 2, at most 50 pages and all ordinary include groups. `--include` can be repeated for `a11y`, `perf`, `network`, `responsive`, `theming`, `styles.detail`, `all` and explicitly `responsive.widths`. Width replay is not part of `all`. `--seed-routes seeds.json` takes a JSON array of route strings and disables discovery beyond those seeds.\n\n```sh\nstage1 inspect surface https://example.com --seed-route / --seed-route /about --out ./surface-runs\n```\n\nSurface capture defaults to `style.fingerprint` plus dependencies, depth 0, at most 50 pages, and no discovery. Explicit seeds are the complete candidate set. `--discover` enables bounded same-origin discovery and defaults depth to 2; a nonzero `--crawl-depth` requires it. Allowed `--passes` values (comma-separated) are `web.crawl`, `web.computed_styles`, `style.fingerprint`, `token.guess`, `web.stylesheet_rules`, `style.breakpoints`, `style.theming`.\n\nLighthouse 13.5.0 measures at most the first five available pages in root-then-route order. This is a bounded sample, not a representative sample of page types. Selection and unselected pages are recorded. Explicit responsive width replay selects at most 10 pages, 8 widths and 40 probes per page; reports disclose selection and truncation. Capture budgets do not promise complete site coverage. Review actual pages, failures and first-party health in the run.\n\nBoth capture modes accept `--name`, `--auth` (local browser storage-state JSON), `--device`, `--viewport WxH`, `--sequential`, repeatable `--first-party-host`, `--robots-override <reason>`, `--sampling compact|full`, and evidence retention switches. Respect the site's access rules; an override reason is recorded.\n\n`--sampling` sets how many elements per page computed styles are read from. `full` (the default) reads up to 250 elements per page and 50 per element group. `compact` reads up to 120 and 24, with shorter selectors. Computed styles are read from a replay of each saved page with its scripts made inert. Each record says whether its element was painted in the captured state at the capture width, and why not, and sampling reads painted elements first. Each record also says where each judged value came from (the site's CSS, the browser's own stylesheet, or nothing declared, so the CSS initial value), read from the capture browser, whose build and colour scheme the run manifest records. The crawl also records which parts of each page a third party's script inserted, and records inside them name that host. The run manifest records the mode with the Stage1 version that made the run. `--keep-evidence` (the default) and `--no-keep-evidence` only decide whether evidence is retained; they change nothing a capture records. Output precedence is `--out`, then `STAGE1_OUTPUT_ROOT`, then `./out`. Relative CLI paths resolve at invocation. Capture help lists exact flags. Unknown commands, options, groups and pass IDs fail.\n\nDevice profile names are case- and space-sensitive, for example `--device \"iPhone 15\"` or `--device \"Pixel 7\"`. Use `--viewport 1440x900` for a custom viewport. Run `stage1 inspect app --help` or `stage1 inspect surface --help` for command-specific options.\n\nLocal browsing is the default, even if provider settings are inherited. For your own Bright Data Scraping Browser account, supply its authenticated `wss` CDP endpoint in `STAGE1_SCRAPING_BROWSER_CDP_URL` through your environment, then explicitly select remote:\n\n```sh\nstage1 inspect app --url https://example.com --out ./remote-runs --browser remote --max-pages 1\n```\n\nProvision and pay for that provider account yourself. Do not paste credentials into commands, shared configuration, captures or issue reports. No account is bundled. Missing/invalid remote configuration fails; Stage1 never silently switches to local. Actual live-pass tier and health are recorded. Optional `STAGE1_SCRAPING_BROWSER_COUNTRY` selects the provider country. Inherited enable flags alone do not authorize paid capture.\n\n## Multi-site suites and discovery\n\nDiscover candidates from any newline URL list or JSON array of URL strings / `{\"url\":\"…\"}` objects:\n\n```sh\nstage1 discover --from ./urls.txt --name public-sites --count 10 --keep-path --out ./runs\nstage1 inspect suite --config GENERATED_SUITE_YAML --out ./runs --sequential\nstage1 view SUITE_RUN_DIR --port 0\n```\n\nDiscovery checks robots and reachability before including a URL. It keeps every candidate and its exclusion reason, deduplicates by exact origin (including port), follows at most ten redirects with a robots check at each hop, and defaults to ten included origins and a 10,000 ms request deadline (`--timeout-ms`). `--keep-path` retains a candidate path as an explicit seed; otherwise the origin root is used. A robots refusal or unavailable host stays excluded. With no accepted candidates it writes a discovery receipt, no config, and exits 1. Discovery uses ordinary HTTP requests and no paid browser. It offers no robots override.\n\nReview the generated config before capture. This strict example captures one seed per target:\n\n```yaml\nsuite:\n  name: public-sites\n  apps:\n    - name: First public site\n      targetId: first\n      url: https://example.com/\n      seedRoutes: [/]\n      maxPages: 1\n    - name: Second public site\n      targetId: second\n      url: https://example.org/\n      seedRoutes: [/]\n      maxPages: 1\ninclude: [a11y, styles.detail]\n```\n\nUnknown fields and duplicate target identifiers are refused. `targetId` defaults to the name's slug. URLs must be HTTP(S) without embedded credentials. `include` defaults to `[all]`; per-target `include` overrides it. Targets run sequentially; `--sequential` also orders each target's passes. Each target uses local browsing by default, explicit seed bounds, at most five Lighthouse pages, and no web-unlocker fallback, regardless of inherited provider enable flags. Per-target `browser: remote` is the explicit paid-browser opt-in. No suite-wide tier or robots override flag exists.\n\nPer-target settings also include `crawlDepth`, `device`, `viewport`, `firstPartyHosts`, `repoPath`, `figmaFileKey`, `auth: {storageState: private-file.json}`, and `api` with the same named fields as MCP app inspection. Local file references resolve relative to the config. Credentials remain file/environment references. An authorized exception to robots is `robots_override: {reason: your recorded reason}` on the individual target; that reason reaches crawl/API evidence and the suite's robots summary.\n\nThe run lives at `runs/suites/SUITE_ID/RUN_ID/`. Every attempted target has an ordinary run under `targets/TARGET_ID/`; the root attests its child manifests and files. Every configured target keeps a captured, failed or unscanned state with a reason and robots status. Partial or cancelled suites remain inspectable and return failure. `#/suite` puts measured style values, literal structure presence, persisted facet spellings, JSON-LD types, API fields/endpoints and accessibility results beside each other. Needs-review and violations stay separate. Missing measurement is not zero; recorded input caps and dropped counts remain visible. Target links open the ordinary site views. No similarity score or semantic equivalence is inferred.\n\nResume is explicit:\n\n```sh\nstage1 inspect suite --config ./suite.yaml --out ./runs --resume RUN_ID\nstage1 inspect suite --config ./suite.yaml --out ./runs --resume\n```\n\nThe second form selects the unambiguous latest recorded suite. Resume verifies the resolved config, root/child identities, hashes and actual files. Only fully verified targets whose passes all succeeded are retained; incomplete targets are recaptured. Changed inputs, changed bytes, unknown extra files, aliases and ambiguous latest selection are refused. Completed verified runs stay byte-identical. Legacy suite records without the integrity contract cannot resume. One CLI writer or MCP server owns an output root at a time; stop that server before running a CLI capture against the same root. A dead process's lease can be reclaimed; restart never resumes capture automatically.\n\nExport adds an explicit public-subject approval for **every** configured target:\n\n```sh\nstage1 view SUITE_RUN_DIR --export ./share-suite --approve-sharing RUN_ID --approve-target first --approve-target second\n```\n\nAn authenticated target also needs `--approve-authenticated-target TARGET_ID` and the existing root `--approve-authenticated-sharing RUN_ID`. The declaration binds each target identity and child manifest digest. Unapproved targets are named and refused. The export verifies all suite-attested bytes before and after rendering; suite and target links work from the resulting files. Original runs are unchanged.\n\nMCP provides `stage1_discover_suite` (`fromPath`, optional `name`, `count`, `timeoutMs`, `keepPath`) and `stage1_inspect_suite` (`configPath`, optional `sequential`, `keepEvidence`, `sampling`, `resume: true | UUID`). Both return persisted job acknowledgments and use `stage1_job_status`, `stage1_job_result` and `stage1_job_cancel`. Discovery's terminal result includes `suiteConfigPath` or null. Supply absolute input paths inside the configured output root; every local file reference in suite YAML must also resolve inside it. Tool arguments never take credential values. Cancellation retains finished targets; interrupted jobs stay interrupted until an explicit new resume request. `stage1_export` adds `approveTargets` and `approveAuthenticatedTargets` arrays. `stage1_get_artifact` reads a suite aggregate by its JSON filename.\n\n## Guided sessions\n\nGuided capture opens a local browser on the operator's desktop. Sign in and navigate there, then enter `capture <label>` in the terminal to preserve a state. Labels distinguish repeated captures at the same URL. `quit`, window close, or an interrupt ends the session and finalizes the retained evidence.\n\nOpen the completed run with `stage1 view RUN_DIR`. Overview shows recorded session bounds, authentication input, login-state save status, response-body redaction and omitted measurements. Each labelled state opens its own screenshot, page facts and live axe findings, even when several states share a URL. Captured coverage counts retained checkpoints and visited routes; the site's total route/state count remains unknown. Performance, full network tracing and responsive replay are not measured by guided capture. Older evidence without state identities cannot supply state-specific facts or missing live axe results.\n\n```sh\nstage1 capture guided https://example.com --out ./runs --name journey --no-auto-capture --max-captures 100 --idle-timeout 1800\nstage1 inspect guided RUN_DIR/evidence --out ./runs\n```\n\nAutomatic navigation capture is enabled unless `--no-auto-capture` is passed. The defaults are 100 checkpoints and 1800 seconds of inactivity; supported limits are 1–1000 checkpoints and 1–86400 seconds. Operator input, navigation and checkpoints reset the idle timer; status polling does not. Bounds and termination reasons are recorded. The limit refuses additional checkpoints without discarding earlier ones. `inspect guided` creates a fresh discoverable analysis and preserves its source evidence.\n\n`--auth /private/login.json` reads an existing browser storage-state file. `--save-auth /private/saved-login.json` explicitly saves state outside the entire run, with owner-only permissions; `auth` saves it during the session. No credential values or credential-file paths are written into the guided record or job metadata. Keep these files private. Interactive runs require authenticated-sharing approval when exported, even if no input login file was supplied.\n\nFor MCP, use `stage1_guided_start` with `url`, optional `name`, absolute `authStorageStatePath`/`saveAuthPath`, `autoCapture`, `maxCaptures` and `idleTimeoutSeconds`. The server must run on the operator's own desktop. Its first reply is `starting`; poll `stage1_guided_status` with `sessionId` until `running`. Then call `stage1_guided_capture` with `sessionId` and `label`, and finish with `stage1_guided_end` or `stage1_guided_cancel`. Guided and ordinary captures share one active job slot and the same root lease. Closing the window finalizes automatically; repeated end returns the same result.\n\nAfter a server restart, unfinished jobs are `interrupted`. Calling `stage1_guided_end` analyzes their retained evidence into a fresh run; it does not relaunch the browser or rewrite the interrupted capture. `stage1_inspect_guided` takes a completed root-scoped `runId` and also creates a fresh analysis. Use list, artifact and view tools with the resulting run ID. The legacy one-shot guided tool is retired.\n\n## Local .fig comparison\n\nThe value comparison covers colour, font size, radius, spacing, border colour, shadow and font weight. Library component families compare with declared markup. Optional Figma REST metadata adds a comparison of literal CSS token-name references; it does not establish variable bindings.\n\nEach family records its exact match rule. Spacing compares captured raw padding/margin values\nwith spacing/space/padding/margin/gap-named numeric tokens. Border colour compares measured border\ncolours with border/stroke-named colour tokens under the recorded alpha policy. Shadows compare\nordered visible drop/inner-shadow layers by colour (including alpha), pixel offsets, blur, spread\nand inset; unsupported or incomplete effects remain unresolved. These are parameter comparisons,\nnot rendered-pixel comparisons. Font weight compares numeric font-weight-named tokens (1–1000)\nwith captured weights across typefaces; labels such as Regular and Bold are not converted into\nnumbers. Colour conformance pools the declared palette; separate per-collection and per-mode coverage names the\nmode (or tied modes) explaining the most compared occurrences among tokens whose values distinguish\nmodes. Single-mode palettes and unmoded styles are shown separately. Unknown collections do not\nsupport theme inference. Live values no theme mode explains stay visible; coverage never establishes\na clean build.\n\nType is compared per typeface, first against size variables with modes named for that typeface, then\nagainst its text styles. Exact matches are conformant. A size within 0.16px of a moded size is labelled\n\"normalized type (rounding)\"; a typeface with no comparand is unjudged. For a face without a declared\nmode, `redrift --type-factor 'Example Sans=1.06'` declares a factor against its text-style scale (or\nthe kit's unqualified scale when it has no matching styles). Repeat the option for distinct families.\nFactors must be positive decimals at most 4. These matches are \"normalized type (declared factor)\",\nnever conformant. Nothing is fitted to the site.\nMissing design or live values produce `empty_comparand` with a reason and no drift signal.\nComparison headings do not score the site or show conformance ratios. Older analyses retain their\nrecorded results.\n\n\nUse your own exported `design.fig`, a fresh extraction directory and a previously captured run. No remote Figma account is required. Decoded design contents remain local; console output contains counts and filenames.\n\nExtraction writes `fig_local_tokens` 1.7.0. An alias resolves mode by mode, the way Figma resolves it: a step in the variable's own collection uses that mode, and a step in any other collection uses that collection's default, its first mode. Each variable keeps the scopes Figma declares for it, and a collections table names each collection's modes and default. Each text style also records, exactly as the `.fig` holds them, its line height and letter spacing (`{value, units}`) and the weight and normal line height Figma records for its font; a style name such as \"Bold\" is never read as a weight. Variables, collections and styles that Figma has soft-deleted (kept in the file only so older references still resolve) are flagged `soft_deleted`, and comparisons leave them out: the report's `value_join.left_out` counts them by kind. On the public USWDS kit that is 627 of 1,831 tokens, and leaving them out changes no result (0 signals before and after) while the colour names cited fall from 1,354 to 785.\n\n```sh\nstage1 fig-extract ./design.fig --out ./fig-out\nstage1 redrift RUN_DIR --fig-tokens ./fig-out/design.tokens.json --out ./comparison --durable\nstage1 view RUN_DIR --analysis ./comparison --port 0\nstage1 view RUN_DIR --analysis ./comparison --export ./share-comparison --approve-sharing RUN_ID\n```\n\n\nSupply `--figma-library <printed-library-path>` to `redrift`, alone or beside `--fig-tokens`,\nto compare the library with `declared_components`. The Comparison page lists matched,\ndesign-only and site-only records with evidence, plus every library component and set.\nMissing declared markup reads **not measured**. Exact published component keys are read from\nexplicit `data-figma-component-key` on block elements and the local twin index (or REST keys).\nOtherwise names compare by lowercase family head before slash/dot with punctuation as separators.\nNamespaces, aliases and words are not removed. BEM elements/modifiers are evidence, not proof\nthat a design variant rendered. A differing explicit key cannot be overridden by a name match.\nUnmatched records mean unmatched under this rule, not an implementation defect. Captured\npages do not establish whole-site coverage. Historical analyses keep their recorded meaning.\n\n```sh\nstage1 redrift <run-dir> --figma-library <extraction-dir>/<label>.figma-library.json --out <fresh-analysis-dir> --durable\n```\n\nSince 0.5.0, ratios use raw values from full sampling by default. Values explained by capture state, browser defaults, third-party content or the comparison rules are listed separately; they count as neither conformant nor drift. Conformant still means an exact token match, so ratios from 0.3.x, 0.4.0 and 0.5.0 measure different populations and should not be read as a trend.\n\nThe decoder reports filenames derived from the input basename; use those printed names if yours differ. `redrift` writes a separate analysis and preserves its source run. It reports the available evidence on each side, not inferred agreement for missing data. Live values are compared as recorded, not as rounded groups. Each value finding names up to five places it occurs: the page, the element's selector, the property and the computed-style record. For a run captured before 0.4.0, `redrift` recomputes those values from the run's retained computed-style evidence after checking it against the run's own attestation. An occurrence on an element not painted at capture is listed apart with its reason and place, never counted as conformant or drift; each family states how many occurrences it compared. On a run captured before 0.4.0 only an element's own display:none is applied, and other hidden states read \"not recorded on this run\". A value the browser supplied itself is listed apart in the same way, naming the browser build; on a run captured before 0.4.0 it reads \"not recorded on this run\". So are values inside content a third party's script inserted, grouped by host; the site's own markup, even a button that opens such a widget, stays compared. Comparison rules explain non-token values without counting them as conformant, including: a border colour in the kit's palette with no border role, a negated spacing token, and a length relative to the element's own font size (a fixed multiple, or declared in em/ex/ch/cap/lh/ic). Each family publishes the rule that decided which tokens it compared. `--max-signals-per-side` is retained for historical compatibility; new declared-presence records are not capped. The durable analysis directory can be moved with its attested files and supplied to `view --analysis`.\n\nTo inspect a hosted Figma file with your own personal access token, set `FIGMA_TOKEN` in the\nprocess environment and pass only the file key. Stage1 does not load `.env` automatically.\n\n```sh\nstage1 inspect app --url https://example.com --figma-file FILE_KEY --out ./runs\nstage1 redrift RUN_DIR --out ./figma-comparison --durable\nstage1 view RUN_DIR --analysis ./figma-comparison --port 0\n```\n\nMCP uses `stage1_inspect_app.figmaFileKey`, with `FIGMA_TOKEN` set on the server. No CLI flag,\nMCP field, run manifest or artifact accepts or retains the credential. Captures without a file key\nmake no Figma requests. Figma acquisition is recorded as header-authenticated, so exporting its\nrecords also requires `--approve-authenticated-sharing RUN_ID` (or MCP `approveAuthenticatedSharing`),\nin addition to the ordinary sharing declaration. This does not imply a logged-in browser. The Comparison page shows library records, declared variant properties,\ncomponent descriptions, status values, native annotations and clearly labelled naming hints even\nbefore a comparison is created. Token-name references in descriptions and names activate the\nliteral-name comparison against captured custom-property declarations, including those within recorded layers and conditions. Matching names do not prove variable bindings, effective use or equal design values.\n\nRequests use Figma's REST files API: 30 seconds and 20 MiB per response, at most 24 requests per\npass, 50 component-set IDs per batch and 1,000 sets per pass. A 429 stops requests in that pass and\nreports `Retry-After`; there are no automatic retries. Scope failures retain Figma's scope message.\nUnpublished drafts fall back to a file tree limited to depth 5; fallback node IDs are never treated\nas published component keys. Native annotations and shared/plugin presence are read within that\nsame depth. Deeper content is outside the measurement. A partial result remains labelled partial;\nmissing access never means the file has no declarations. Name-derived hints carry no confidence\nscores and are never promoted to plugin-declared intent merely because plugin data exists.\n\nYou can also supply a design system's local CSS or SCSS declarations:\n\n```sh\nstage1 design-tokens ./tokens.scss ./design.css --out ./source-tokens\nstage1 redrift RUN_DIR --design-tokens ./source-tokens/design_source_tokens.json --out ./source-comparison --durable\nstage1 view RUN_DIR --analysis ./source-comparison --port 0\n```\n\nAdd `--fig-tokens` to compare both design sources independently. Comparison and Signals name\nthe source of each result; a value found in one source does not fill a gap in the other.\n\n### What to look at first: the comparison as pictures\n\nA comparison also writes `signal_places` 1.0.0 beside its report, read from the capture's retained evidence under its\nattestation. For each off-system value it records:\n\n- the captured pages the value occurs on, counted over every occurrence, not only the five examples;\n- for each recorded place, the page's screenshot and its pixel size, the element's box, and whether the box falls inside\n  that first screen;\n- the CSS the site wrote there, the custom properties that CSS names, and the component (a `data-slot` value, or a block\n  of the site's own BEM convention) and landmark around the element.\n\nA file that is gone or no longer matches is listed in `not_read`, never guessed.\n\n#/comparison opens with \"What to look at first\". It groups the values by the token their CSS names: a design token, the\nsite's own custom property, or none. Each group shows the token's design value, the live swatches, \"N values on P\npages\" and one outlined place. The order is printed (pages, then values, then name), and nothing is scored.\n\nEach signal shows the live swatch beside the design token its CSS names and the nearest design value, by the same rule\nas `stage1 nearest`. It outlines every place on its page's first screen, or says why it cannot: below the first screen,\npartly framed, not painted, or no screenshot. A colour outside sRGB is said, never mapped.\n\nThe picture is the crawl's first screen (a 1280×720 JPEG). The outline is where the replay of the saved page placed the\nelement, so the two loads can differ, and the picture's colours are approximate. An analysis made before 0.7.0 says its\nplaces were not recorded. An export adds no files, because the crops are drawn over the screenshots it already\ncarries.\n\nOn ui.shadcn.com read at rest, 27 of 67 off-system values have an outlined place in the first screen, 39 sit only\nbelow it, and 1 is partly framed. Of the 67, 4 name a theme token in their CSS, 53 name only the site's own custom\nproperties (such as the colours page's `--bg` and the code theme's `--shiki-light`), 8 write the value directly, and 2\nare mixed.\nThe new artifact records file hashes, line/column locations, alias declaration IDs, unresolved\nreasons and the conversion basis for every resolved `rem` value. Existing destinations are refused.\n\nExtraction accepts at most 50 distinctly named `.css`/`.scss` files, 10 MiB total, and 10,000\nrelevant declarations. It parses syntax locally with PostCSS and postcss-scss. It does not fetch\nimports, run Sass, evaluate CSS cascade, or execute project configuration. Literal colours,\nnumbers, pixel/rem dimensions, explicit shadows, simple font stacks and explicit variable aliases\nare supported. CSS aliases resolve within their declaration block, an unambiguous unconditional\n`:root`/`html`/`:host` block (including lists), or a supplied `@theme`/`@theme inline` block.\nConstant `calc()` arithmetic over resolved numbers and px/rem lengths is labelled `derived`,\nwith its root-size basis. Relative element units, functions, incompatible units and division by\nzero remain unresolved. SCSS aliases resolve unique top-level variables among the supplied files.\nMissing, cyclic or ambiguous aliases, Sass functions/maps/arithmetic/control flow, nesting, and\nunsupported units remain unresolved. Compile complex Sass with your design system's own build\nfirst, then supply its CSS; this preparation is outside Stage1.\n\nTypography pairs literal sizes with an unambiguous explicit font-family on the same selector in\nthe same file, including media declarations. Inherited families are not guessed. This is an\ninventory of declarations across conditions, not a claim that every value applies at every\nviewport. `--initial-font-size <px>` records the initial browser font-size basis (default 16);\nan unconditional `html`/`:root` font-size adjusts it. Conflicting or conditional roots leave `rem`\nunresolved. This basis must match the capture environment. Type comparisons require a fingerprint\nwith sizes recorded by typeface; older pooled fingerprints read as unmeasured. The view lists\nresolved and unresolved declarations so an incomplete source cannot appear to be a complete scale.\n\n### DTCG, Tokens Studio and native Figma token files\n\n`design-tokens` also writes `design_source_tokens 1.1.0` from local JSON. Supply JSON separately\nfrom CSS/SCSS. The same `redrift --design-tokens` command compares it with a retained capture.\nComparison shows each collection, mode, declared type, grammar, alias and source-file JSON pointer.\nA token with any unresolved mode counts as unresolved; its other resolved modes remain usable.\n\nA DTCG 2025.10 file (`brand.json`):\n\n```json\n{\n  \"ink\": { \"$type\": \"color\", \"$value\": { \"colorSpace\": \"srgb\", \"components\": [0, 0, 0] } },\n  \"space\": { \"$type\": \"dimension\", \"$value\": { \"value\": 0.5, \"unit\": \"rem\" } },\n  \"border\": { \"$value\": \"{ink}\" }\n}\n```\n\n```sh\nstage1 design-tokens brand.json --out ./brand-tokens\n```\n\nTypes come from an explicit token type, a whole-token alias's resolved type, then the nearest\ngroup type. Values never determine their own type. Curly references identify whole tokens;\n`$root` must be explicit. A value such as `{ \"$ref\": \"#/ink/$value/components/0\" }` uses an\nRFC 6901 property/array pointer. `$extends` deep-merges groups and replaces whole tokens.\nDeprecated metadata is retained, including a child's `false` override; it does not remove values\nfrom the comparison. Nonstandard grammar is labelled per token and per mode. A DTCG dimension needs\n`{value, unit}`; a bare number stays unresolved.\n\nA Resolver (`brand.resolver.json`) combines local files in declared order, then resolves aliases:\n\n```json\n{\n  \"version\": \"2025.10\",\n  \"sets\": { \"base\": { \"sources\": [{ \"$ref\": \"./brand.json\" }] } },\n  \"modifiers\": { \"theme\": {\n    \"contexts\": { \"Light\": [{ \"$ref\": \"./light.json\" }], \"Dark\": [{ \"$ref\": \"./dark.json\" }] },\n    \"default\": \"Light\"\n  } },\n  \"resolutionOrder\": [{ \"$ref\": \"#/sets/base\" }, { \"$ref\": \"#/modifiers/theme\" }]\n}\n```\n\n```sh\nstage1 design-tokens brand.resolver.json --out ./resolved-brand\n```\n\nEach modifier becomes a collection and each context a mode. When enumerating one modifier,\nothers use their declared defaults; combinations are not multiplied. Referenced local JSON\nfiles load within the directories of explicitly supplied inputs. URLs, escaping symlinks and\nunavailable files never fetch content; missing values carry reasons. JSON5/JSONC is not accepted.\n\nTokens Studio supports both its legacy form and its `$` form, including string dimensions:\n\n```json\n{\n  \"legacy\": { \"type\": \"dimension\", \"value\": \"8px\" },\n  \"modern\": { \"$type\": \"dimension\", \"$value\": \"{legacy} * 2\" }\n}\n```\n\n```sh\nstage1 design-tokens studio.json --out ./studio-tokens\nstage1 design-tokens './tokens/$themes.json' --out ./studio-themes\n```\n\nWith `$themes.json`, theme `group` becomes collection and `name` becomes mode. `tokenSetOrder`\nfrom sibling `$metadata.json` controls merging. Enabled sets emit tokens; source sets only resolve\naliases; disabled sets are excluded. Duplicate theme IDs merge their selected sets when their\nname/group agree. Missing selected files are listed as warnings. For example:\n\n```json\n[{ \"id\": \"light\", \"group\": \"Brand\", \"name\": \"Light\",\n   \"selectedTokenSets\": { \"primitives\": \"source\", \"semantic/light\": \"enabled\" } }]\n```\n\nNative Figma writes one file per mode, with no collection name. A minimal native-shaped file is:\n\n```json\n{\n  \"$extensions\": { \"com.figma.modeName\": \"Light\" },\n  \"space\": { \"$type\": \"number\", \"$value\": 8,\n    \"$extensions\": { \"com.figma.variableId\": \"VariableID:1:2\", \"com.figma.scopes\": [\"GAP\"] } }\n}\n```\n\n```sh\nstage1 design-tokens Light.tokens.json Dark.tokens.json --collection Brand --out ./figma-tokens\n```\n\nMode names come from metadata, falling back to the file stem. Collection defaults to the file\nstem too; use `--collection` to combine exports deliberately. Native string/boolean grammar is\nlabelled `figma`. Literal values remain usable when Figma's separate alias metadata names a target\noutside the supplied files. Exact source handles link supplied targets; display names never do.\nSource-only targets have provenance but no emitted graph edge. Opaque extension payloads are not\ncopied. Native variable exports omit styles; this cannot replace style-backed `.fig` values.\n\nOnly constant addition, subtraction, multiplication and division over resolved numbers/dimensions\nare evaluated, labelled `derived`. Functions, division by zero, incompatible units and vendor-derived\nvalues (such as Blueprint's `com.blueprint.derive`) remain unresolved. Nothing is executed. Colors\nuse the same space-aware comparison as captures; hex fallbacks remain separately declared. An\ninvalid optional hex fallback is warned and ignored. System colors need an unavailable environment\nand stay unresolved. Typography declares its own typeface; a standalone font-size scope cannot\ninvent one. Generic dimensions do not imply spacing or radius. Named Figma scopes and explicit\nsemantic types supplement name rules; layout widths still cannot become spacing. Numeric native\nFigma dimensions use the existing pixel comparison convention. JSON `rem` uses the recorded\n`--initial-font-size` basis, default 16px.\n\nThe bounds are 50 files, 10 MiB, 10,000 tokens or (collection, token, mode) values, 64 nesting/alias\nlevels, 100 contexts, and 100,000 resolution steps for reading the files and again for each context.\nStandalone unmoded files merge in argument order; later whole tokens replace earlier ones. Use a\nResolver to declare different contexts instead of inferring modes from folder names. A Resolver token\nis filed under the set or modifier that defines it: one a modifier's contexts define has one value per\ncontext (other modifiers at their defaults), and one only sets define has a single value under the\nlast set that defines it. Original source bytes and historical captures remain unchanged.\n\n### DTCG out: `stage1 dtcg-export`\n\n```sh\nstage1 dtcg-export --fig-tokens ./fig-out/design.tokens.json --out ./design-dtcg\nstage1 dtcg-export --design-tokens ./design/design_source_tokens.json --out ./css-dtcg\nstage1 dtcg-export --run RUN_DIR --out ./live-dtcg\n```\n\nGive exactly one source: a `.fig` extraction, a CSS/SCSS reading from `stage1 design-tokens`, or a single-site capture run.\n\nThis writes your kit's variables as DTCG 2025.10 token sets plus a Resolver: `sets/<collection>.tokens.json` for a collection with one mode, `sets/<collection>/<mode>.tokens.json` for each mode of the others, and `<kit>.resolver.json`, whose modifiers default to each collection's default mode. Every token sits under its collection as the top-level group, and its name nests at `/`, so the same name in two collections stays two tokens. Aliases are `{…}` references; colours are `{colorSpace, components, alpha, hex}` objects; `$extensions` keep `com.figma.variableId` and `com.figma.scopes`. Figma's string and boolean variables use the `string` and `boolean` types Figma's own export uses, which DTCG 2025.10 does not define; the receipt counts them.\n\nBefore anything is kept, Stage1 reads the export back with its own reader. Every value must equal the source exactly, each under its own collection and mode, and every alias must come back as a reference. On any mismatch the command exits 1, names the mismatches and leaves nothing behind; `--out` must be new or empty. `dtcg_export.json` (`dtcg_export 1.1.0`) records the files and their SHA-256s, the counts written and read back, each collection's default mode and why, merged and conflicting duplicates, and everything not written with its reason: soft-deleted variables and styles, values the source does not hold, and aliases into a deleted variable (written as their values). A live text style is written as DTCG `typography` when every member is recorded: line height `RAW` x is x, `PIXELS` x is x ÷ font size, and `PERCENT` x is x percent of the font's normal line height (Figma's \"Auto\" is 100); letter spacing `PERCENT` x is x percent of the font size, `PIXELS` x is x px. A style without a recorded member is listed in `missing_fields` with exactly the members it lacks, never completed with an invented value. Exported from the public USWDS design kit, that is 41 files, 1,190 tokens (its one live text style among them), 2,320 values and 1,440 aliases, all read back equal.\n\n**From CSS/SCSS** (`--design-tokens`), only declarations for the document root become tokens, each named by its custom property without the leading `--`, which it keeps in `$extensions[\"ai.aquex.stage1.css_name\"]`: unconditional `:root`, `:host` or `html` declarations form the `:root` set, `@theme` blocks form sets named by the at-rule, and a class or attribute selector that re-declares root names (such as `.dark`) becomes a modifier whose `:root` context holds the root values of the names it re-declares. A `var()` in `@theme` therefore resolves per context, as the cascade does. `var(--x)` becomes the reference `{x}`; a `calc()` value is written as its computed value and listed; colours keep their own space; dimensions keep their declared px or rem. Declarations for other selectors apply to matching elements, not to the document, and are listed with their context, as are unresolved values. A JSON reading is already DTCG or Tokens Studio and is refused. shadcn's `globals.css`: 80 tokens, 115 values and 41 aliases read back equal; 54 declarations are listed (element rules, unresolved values and computed `calc()` values).\n\n**From a live site** (`--run`), Stage1 first verifies the run against its manifest, then writes the custom properties the capture computed at the effective root, named without the leading `--` and keeping the property name in `ai.aquex.stage1.css_name`, plus a `.dark` modifier made only from declared `.dark` blocks (including blocks under `@supports`, which the receipt names). A property whose value differs between routes is listed, not averaged. A value is written only when its DTCG type can be read from the value itself (colour, px/rem dimension, number, `cubic-bezier()`); `calc()`, other units, keywords and font stacks are listed, never given an invented type. Each written root token carries `ai.aquex.stage1.observed` with value-matched occurrence and page counts from the run's computed styles: equal values, not uses of the variable, since nothing records which `var()` produced a value. The receipt states how many routes and effective-root variables the capture held. ui.shadcn.com (capture of 40 routes): 365 effective-root variables, 312 tokens and 352 values written and read back equal, 53 listed with reasons. designsystem.digital.gov: 0 effective-root variables on 40 routes, because USWDS compiles its Sass tokens into literal values; its 11 custom properties belong to a web component's shadow root, so the export is empty and says so.\n\n## Baselines and `stage1 diff`\n\nRecord what a run found, then compare later runs with it:\n\n```sh\nstage1 diff ./out/analysis/<analysis-id> --write-baseline .stage1/baseline.json\nstage1 diff ./out/analysis/<later-analysis-id> --baseline .stage1/baseline.json\n```\n\n`<run-dir>` is a durable analysis (`redrift --durable`) or a single-site capture run, so a team without a design file can still compare accessibility and IA. The baseline (`check_baseline 1.0.0`) holds each finding's identity, which families were measured, and the pins below. It is never overwritten and never written inside the run it describes; commit it beside your code. The run is verified against its attestation first and is never modified.\n\nA finding's identity is exact. A drift value is its comparison surface, family, value as recorded and typeface. An explained value adds its category, and the origin for a browser default. An accessibility violation is its axe rule and impact; affected selectors are evidence, because many are generated ids. Presence is the site block or the design node. IA is a route's page type, or a navigation label and link. A Lighthouse insight is its route and id. Example locations are evidence, not identity, and values are never grouped: a value that moves in its last digit is a new finding, and the old one is resolved.\n\n`diff` lists new, resolved and changed findings (changed means the same identity with different occurrence counts), with no totals. When the two sides are not comparable it lists nothing, exits 2 and names every pin that differs: the capture and analysis Stage1 versions, the drift report version, the Lighthouse version, the route set, the pages accessibility and Lighthouse measured, the sampling depth, and the design-input files. A family a run did not measure is reported as not measured with its reason, never as zero. Lighthouse insights move between identical captures (a same-release USWDS recapture 20 minutes apart gained two and lost one), so treat them as report-only. Multi-site suites are not supported by `diff` in this release.\n\n## Your team's rules and `stage1 check`\n\nThe measurements can be common; which of them count for your product, and which findings stop a release, are your team's call. Write them down in `.stage1/rules.yaml`:\n\n```yaml\nrules_version: 1\nfamilies: [color, radius, border_color, a11y]\nrules:\n  - id: no-new-off-theme-colour\n    select: { finding: value_drift, value_family: [color, border_color] }\n    when: new\n    block: true\n  - id: no-critical-a11y\n    select: { finding: a11y_violation, impact: critical }\n    when: present\n    block: true\n  - id: radius-on-theme\n    select: { finding: value_drift, value_family: radius }\n    when: present\n    block: false\nbaseline_policy:\n  new_unexplained_drift: block\nwaivers:\n  - finding: { finding: a11y_violation, rule_id: button-name, impact: critical }\n    reason: \"Every affected node is inside an embedded video player\"\n    expires: 2026-12-31\n```\n\n```sh\nstage1 check ./out/analysis/<analysis-id> --rules .stage1/rules.yaml --baseline .stage1/baseline.json --out ./stage1-check\n```\n\n- `families` lists what your product counts: the value families `color`, `font_size`, `radius`, `spacing`, `border_color`, `shadow` and `font_weight`, plus `a11y`, `presence`, `ia` and `perf`. A rule selects only findings in counted families.\n- `select` names a finding type (`value_drift`, `explained`, `a11y_violation`, `presence_site_only`, `presence_design_only`, `ia_page_type`, `ia_nav_item`, `perf_insight`) and, optionally, exact values of its identity fields (one value or a list).\n- `when: present` fails when a selected finding exists; `when: new` fails when one is new since the baseline. `block: true` makes that failure fail the job.\n- With a baseline, `baseline_policy.new_unexplained_drift: block` (the default) also fails on any new off-system value in a counted value family; `report` lists them without blocking.\n- A waiver suppresses exactly one finding identity until its date, and the report names what it suppressed; after the date the rule fails again and names the expired waiver. `--on YYYY-MM-DD` sets the date waivers are judged by (default: today in UTC).\n- There are no thresholds, counts, ratios or scores to select, and severity is not selectable: rules block on findings, never on a number. A rules file that tries is refused, naming the field.\n- Lighthouse insights change between identical captures, so a `perf` rule may report but never block.\n\n`check` writes `check_report.json` to a new directory: the pins and whether the baseline was comparable, each counted family's state, each rule's state (passed, failed, or not measured with its reason) with the findings behind it, the waivers, and the exit code. It holds no totals or scores. It exits 0 when no blocking rule failed, 1 when one did, and 2 when the check could not be made: an invalid or unreadable rules file, run or baseline; a broken attestation; a baseline that is not comparable; a blocking rule on a family the run did not measure; or a blocking `when: new` rule without a baseline. When the inputs were readable, the report is written even for exit 2, so a CI artifact shows the cause. This follows the model of linters and accessibility test tools such as ESLint, Lighthouse CI and axe-core, where a team configures which rules apply and which failures stop a build.\n\nEvery `value_drift` finding in a report (`check_report 1.1.0`) also carries `nearest`: the measured distance to the design value or values nearest it, with their token names, from the same rule as `stage1 nearest` below. It is evidence, like the examples. It never changes a finding's identity, a rule's state or the exit code, and no rule can select on it.\n\n## The nearest token: `stage1 nearest`\n\n```sh\nstage1 nearest ./out/analysis/<analysis-id> --out ./nearest [--family color border_color radius]\n```\n\nFor every value a comparison judged, `nearest` names the design value or values nearest it and the distance, in `nearest_tokens.json` in a new directory. It reads the run under its attestation and never writes into it.\n\n- **Candidates** are exactly the design values the comparison compared, from the comparison's own builder. Soft-deleted `.fig` content is never named.\n- **Distance:** colours in ΔE OK, the Euclidean distance in OKLab (CSS Color 4's own space), to 4 decimal places, with no gamut mapping. Radius, spacing and font sizes in px to 0.01, and font weights in weight units. Shadows are not measured in this release.\n- **Ties** are listed whole, never broken. `next` names the second-nearest distance, so a close call is visible. There is no threshold and no cap.\n- **State** (conformant, explained or off-system) is the comparison's. A distance never decides it: a value one channel step from a token is still off-system.\n- Each named token lists the modes that carry the value and its alias target. For border colours, the border-role nearest comes first and the whole palette's nearest is listed apart.\n- A family with nothing to measure says so, with the reason, never zero.\n\nA nearest value is a measurement, not a suggested replacement. `0px → --radius-sm at 6px` says how far the square corner is from the nearest radius token; it does not say the corner should be rounded. On ui.shadcn.com's 0.7.0 comparison of record, the 58 off-system colours sit between 0.0020 and 0.2523 from their nearest theme colour (median 0.0576), and 23 of them have a runner-up within 0.005. The command exits 0 when it wrote the report and 1 when it could not, naming why.\n\n## Run the check in GitHub Actions\n\nThis workflow captures a declared set of pages on every pull request, compares them with your design tokens and runs your rules. The job fails when a blocking rule fails (exit 1) or when the check could not be made (exit 2). Commit three files beside it: `.stage1/routes.json`, the pages to capture (for example `[\"/\", \"/docs/installation\", \"/docs/components/base/button\"]`); `.stage1/rules.yaml`, your rules from the section above; and `.stage1/baseline.json`, the findings you have accepted.\n\n```yaml\nname: Stage1 check\non:\n  pull_request:\n  workflow_dispatch:\npermissions:\n  contents: read\njobs:\n  stage1:\n    runs-on: ubuntu-24.04\n    timeout-minutes: 30\n    steps:\n      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4\n      - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4\n        with:\n          node-version: '24'\n      - run: npm install --global @aquex/stage1@0.7.0\n      - run: stage1 browser setup --with-deps\n      - name: Capture the declared pages\n        run: |\n          stage1 inspect app --url https://staging.example.com/ --seed-routes .stage1/routes.json --crawl-depth 0 \\\n            --max-pages 3 --sampling compact --sequential --out \"$RUNNER_TEMP/capture\" > \"$RUNNER_TEMP/capture.json\"\n          echo \"RUN_DIR=$(node -p \"require('$RUNNER_TEMP/capture.json').runDir\")\" >> \"$GITHUB_ENV\"\n      - name: Compare with the design tokens\n        run: |\n          stage1 design-tokens src/styles/globals.css --out \"$RUNNER_TEMP/design\"\n          stage1 redrift \"$RUN_DIR\" --design-tokens \"$RUNNER_TEMP/design/design_source_tokens.json\" --durable --out \"$RUNNER_TEMP/analysis\"\n      - name: This run's baseline (commit it to accept what this run found)\n        run: stage1 diff \"$RUNNER_TEMP/analysis\" --write-baseline \"$RUNNER_TEMP/stage1/baseline.json\" > /dev/null\n      - name: Your rules\n        run: stage1 check \"$RUNNER_TEMP/analysis\" --rules .stage1/rules.yaml --baseline .stage1/baseline.json --out \"$RUNNER_TEMP/stage1/check\"\n      - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4\n        if: always()\n        with:\n          name: stage1\n          path: ${{ runner.temp }}/stage1/\n```\n\n- **The route set** is `.stage1/routes.json`. `--crawl-depth 0` captures those pages and no others; set `--max-pages` to their number. **The sampling depth** is `--sampling compact` (or `full`, the slower default). The baseline pins both, so changing either is a deliberate re-baseline, never a silent difference.\n- **The exit code is the job's result:** 0 when no blocking rule failed, 1 when one did, 2 when the check could not be made. `check_report.json` in the uploaded artifact names the rule, the findings or the cause. `stdout` carries only each command's JSON result; progress goes to stderr.\n- **Adopt a baseline:** run the workflow once from the Actions tab. Its check exits 2 because `.stage1/baseline.json` does not exist yet. Download the run's `stage1` artifact and commit its `baseline.json` as `.stage1/baseline.json`.\n- **Update the baseline** the same way: replace `.stage1/baseline.json` with the `baseline.json` of a run whose findings you reviewed, in a commit of its own. Take it from a CI run, not a local one, so both sides come from the same capture environment. A new Stage1, Lighthouse or design-token file, or a changed route set or sampling depth, makes the old baseline not comparable: the check exits 2 and names the pin, and the fix is a new baseline.\n- **Without a design file,** skip the comparison step and pass `\"$RUN_DIR\"` to `diff` and `check`: accessibility and IA rules work on a capture run.\n- Pin the Stage1 version in `npm install`, so an upgrade is a reviewed change; the baseline pins it too.\n\nMeasured on GitHub's `ubuntu-24.04` runner with these steps against three ui.shadcn.com pages, in two runs: `stage1 browser setup --with-deps` took 25 seconds, each of four captures 248–345 seconds and each comparison 1 second. Capture ran headless with no xvfb and no display, and no pass failed or degraded. Each run exited 0 with the rules above and 1 with a planted blocking rule. The no-design-file variant on three designsystem.digital.gov pages captured in 125 seconds and exited 0 with accessibility and IA rules and 1 with a planted one. Same-release noise, measured in both runs: two captures of the same three pages with the same build, four to six minutes apart, were comparable. No value, accessibility or IA finding was new, resolved or changed; Lighthouse insights moved (3 new and 1 resolved, then 2 new and 1 resolved), which is why a `perf` rule can report but never block.\n\n## MCP clients\n\nAfter installation, configure a stdio client with an absolute writable output root. Replace the example root with a real local path (Windows JSON paths need escaped backslashes). If your client cannot find the global executable, use its absolute installed path.\n\n```json\n{\n  \"mcpServers\": {\n    \"stage1\": {\n      \"command\": \"stage1-mcp\",\n      \"args\": [\"--out\", \"/absolute/stage1-runs\"]\n    }\n  }\n}\n```\n\nWithout a global install, use `\"command\": \"npx\"` with `\"args\": [\"-y\", \"--package\", \"@aquex/stage1@0.7.0\", \"stage1-mcp\", \"--out\", \"/absolute/stage1-runs\"]`. A bare `npx @aquex/stage1` runs the `stage1` CLI, not the server.\n\n`STAGE1_OUTPUT_ROOT` is an alternative; explicit `--out` wins. Missing, relative or unwritable roots fail before capture. One server owns a root; one capture runs at a time. All list/read/export operations stay within that root. Do not put provider secrets into a shared client configuration.\n\nStart `stage1_inspect_app` with `{\"url\":\"https://example.com\",\"maxPages\":1}` or `stage1_inspect_surface` with its surface options (both also take `sampling`: `compact` or `full`). Valid capture requests return a job acknowledgment, not capture success. Invalid target schemes, embedded URL credentials, API options, repositories or suite inputs return `isError: true` with `{ code: \"CAPTURE_REFUSED\", message }` before creating a job, run record or site request. The message names the validation rule without echoing the submitted URL or credentials. MCP input-schema violations remain protocol errors. Poll `stage1_job_status` with `jobId`, then call `stage1_job_result`. Use `stage1_job_cancel` to cancel. Status remains responsive during capture; a second capture returns busy. Job metadata survives restart; unfinished jobs become interrupted and do not resume paid work. Remove retained terminal metadata locally when no longer needed.\n\nOther tools are `stage1_list_runs`, `stage1_list_analyses`, `stage1_get_artifact`, `stage1_check`, `stage1_nearest_tokens`, `stage1_fig_extract`, `stage1_design_tokens`, `stage1_redrift`, `stage1_view`, and `stage1_export`. Artifact reads take a run ID or an analysis ID and an attested artifact key, not an arbitrary path; `pointer` (RFC 6901) selects a subtree, and a response over `maxChars` (default 40,000; at most 1,000,000) is refused with `OVER_CAP`, the cap and the full size, never cut. `stage1_list_analyses` lists durable analyses newest first with their source run and artifact names. `stage1_check` applies a rules file (and optionally a baseline) to a run or analysis with the same engine and the same report bytes as `stage1 check`, writing below the root's `checks` directory; the result carries `exit_code` and the report when it fits `maxChars`. `stage1_nearest_tokens` takes an `analysisId` or `runId` and returns the same report as `stage1 nearest`, written below the root's `nearest` directory, or with a `url` and exactly one of `designTokens`, `figTokens` or local `tokenFiles` (optional `routes`) it starts one job: a surface capture of that page, a durable comparison, then the report, which `stage1_job_result` returns. Failures are named: `UNKNOWN_ID`, `OUTSIDE_ROOT`, `OVER_CAP`, `BAD_POINTER`, `ATTESTATION_MISMATCH` and `INVALID_INPUT`. Fig extraction takes absolute local file paths and returns counts/filenames below the configured root. Design extraction takes absolute `files`, a simple `outName`, and optional `initialFontSizePx` (default 16), writing below the configured root's `design` directory. Redrift takes a `runId` plus optional absolute `figmaLibrary`/`figTokens`/`designTokens` paths and optional `typeFactors: [{family, factor}]`, and returns an analysis ID. Type factors have the same validation and meaning as the CLI option. View takes `runId` and optional `analysisId`; export adds required `approveSharing` equal to `runId`, returning a fresh `exportDir`. Unknown properties are rejected. Stdout is JSON-RPC only; diagnostics use stderr.\n\nFor authenticated captures, `stage1_export` also requires `approveAuthenticatedSharing` equal to `runId`.\n\n## Migration and next capabilities\n\nThis distribution supports single-site and multi-site capture, URL-list discovery, bounded API and local repository inspection, run views, approved static export, Figma REST inspection and local .fig comparisons. Internal reconciliation, remote evidence storage and internal maintenance commands are excluded. Existing historical records remain readable when their artifacts are available. There is no compatibility alias for retired producer commands or the old subject-name export switch.\n\nCLI help/success exits 0; invalid input, refused export or a failed capture pass exits 1. Two commands differ: `stage1 check` exits 0 when no blocking rule failed, 1 when one did and 2 when the check could not be made; `stage1 diff` exits 0 when it compared or wrote a baseline and 2 when it could not, and never 1. Usage errors for those two exit 2. SIGINT/SIGTERM preserve truthful failure records and release acquired resources. MCP schema errors are protocol errors; operational failures are structured errors. Report problems to stage1@aquex.ai with the missing measurement and the installed version, without attaching credentials or private capture content.\n\n## Troubleshooting\n\n- **`stage1: command not found`:** ensure your npm global executable directory is on `PATH`, or run `npx --yes --package @aquex/stage1@0.7.0 stage1 --help`. Use the same prefix before other CLI commands. MCP clients may need the absolute path to `stage1-mcp`.\n- **Browser missing:** run `stage1 browser setup` after installing or upgrading Stage1, then retry. Browser revisions belong to the installed runtime; an unrelated Playwright installation may have a different revision. Linux also needs Chromium's system libraries.\n- **View port in use:** use `stage1 view RUN_DIR --port 0` to choose a free local port. Keep the terminal running while using the view; Ctrl-C closes it.\n- **Output root busy:** stop the other CLI capture or MCP server using that root, or choose a separate `--out` directory. Do not remove a live process's lease.\n- **Capture exited 1:** check `failedPasses` and the run's view for the failed measurement and retained evidence. An MCP job acknowledgment is not a completed capture; poll its status and result.\n- **MCP startup failed:** supply a writable absolute `--out` path or `STAGE1_OUTPUT_ROOT`; relative paths are refused. `stage1-mcp --help` and `stage1-mcp --version` work without starting a server.\n- **Export refused:** use a fresh destination outside the source run and the matching run ID in `--approve-sharing`. Authenticated and suite captures need the additional declarations described above.\n- **Something else:** email stage1@aquex.ai with the installed version (`stage1 --version`) and what failed. Do not attach credentials or private capture content.\n\n## API declarations\n\nAdd API evidence to `inspect app` with `--api <base-url>`. Use `--api-spec <url-or-file>` for an OpenAPI/Swagger declaration, or `--api-type graphql --api-graphql-endpoint /graphql` for introspection. The default type is `auto`: it selects GraphQL only when the lowercased `--api` base URL contains `/graphql`; otherwise it selects REST. Use an explicit type for other GraphQL endpoint names. Without an explicit spec, REST checks known declaration locations. It does not call declared operations or probe resources by default. `--api-probe` explicitly permits bounded GET probes when no spec is found.\n\n`--api-max-endpoints` defaults to 100, accepts 1–1000, and caps retained operations and fallback resource requests. Discovery records the bound, observed operation count, truncation, spec location and probe request count. The default HTTP deadline is 10 seconds; known specification-location discovery uses 5 seconds and fallback probes use shorter 2–3-second deadlines. Declarations and introspection respo","readmeFilename":"README.md"}