{"_id":"pixelcheck","_rev":"21-1127924cbad402fb3ffeab1b88eb497f","name":"pixelcheck","dist-tags":{"latest":"2.1.0"},"versions":{"1.0.0":{"name":"pixelcheck","version":"1.0.0","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.0.0","maintainers":[{"name":"waynetaylor","email":"waynetaylorx@gmail.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"497bb99e184291702c58d71d43faa6ade251cc3d","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.0.0.tgz","fileCount":333,"integrity":"sha512-9v1/9joDH2IGiV5a4OIY+Pju4DhKnRuNyl2A2kfFvVBF2dfgOUzj1onFcRJZitA0oZW9dsgfeB9INLoQPZrKWg==","signatures":[{"sig":"MEUCIEVkuZDsrKJ4lNrbBLpsMygbpQsLfzKy5n32UdtYe69TAiEAv8aRfa4D2ND3o/0vJ21LfUbTeZiKCaFe1Uo06SD2L7c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2598524},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=8.0.0","node":">=18.0.0"},"gitHead":"1c157b0f16fef61e9825f6668964deb855f1af31","scripts":{"sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","lint:no-console":"bash scripts/check-no-console.sh","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"waynetaylorx@gmail.com"},"deprecated":"Versions <1.1.4 contained at least one residual reference to a prior dogfood product. v1.1.4 is the first version with a fully clean ship surface. Please upgrade: npm install pixelcheck@1.1.4","repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.6.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.23.0","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^16.6.1","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","@anthropic-ai/sdk":"^0.92.0","@browserbasehq/stagehand":"^2.0.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","typescript":"^5.9.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.0.0_1777726284799_0.8377784330564169","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"pixelcheck","version":"1.0.1","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.0.1","maintainers":[{"name":"waynetaylor","email":"waynetaylorx@gmail.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"37647cb4e395edc0e71757af36c5986fd0d11a4f","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.0.1.tgz","fileCount":362,"integrity":"sha512-uTQ0U5g2m4nXF6rSbf74CCZABXAdNJMECpGat+iIJmomoQQbv/14SAy5LfLPq7uF1z/PThG2xHybVSYKkW21XQ==","signatures":[{"sig":"MEQCIHmaoACjD+Rh6YWiQaVD8t1UCQZOrtlMMfVqdRamQ0FFAiAnRD3HxqUTk639+qjZ9WRmzQ1eYToKh5G1lks455F18A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2654069},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=8.0.0","node":">=18.0.0"},"gitHead":"974c8a654fe59364baca9f4447b8647869641e9b","scripts":{"sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","lint:no-console":"bash scripts/check-no-console.sh","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"waynetaylorx@gmail.com"},"deprecated":"Versions <1.1.4 contained at least one residual reference to a prior dogfood product. v1.1.4 is the first version with a fully clean ship surface. Please upgrade: npm install pixelcheck@1.1.4","repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.6.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.23.0","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^16.6.1","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","@anthropic-ai/sdk":"^0.92.0","@browserbasehq/stagehand":"^2.0.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","typescript":"^5.9.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.0.1_1777731397351_0.7557286705354416","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"pixelcheck","version":"1.1.0","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.1.0","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"2d68505e299c306d4a3918208eee6764a312a3f0","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.1.0.tgz","fileCount":365,"integrity":"sha512-tOMvbT9jUxvOgiBH26NRHsbg7t9QtgJuO+f0KAuZL2T+xMKGcT0x8MG9+qV/9hkYF/hlETOT3Oz8wMm91wbL1Q==","signatures":[{"sig":"MEYCIQClQXuNcQEIPUFgebb1iRJ8G4xPzk8VadBxCZR2R2YsTwIhAKOKdnp3cqU1/YN8StehU7fNioUA9MbqVLvq38U1PSVb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2691374},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=8.0.0","node":">=18.0.0"},"gitHead":"66e4a799d657449051dc0c1bee6cdb7742ad131e","scripts":{"sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","lint:no-console":"bash scripts/check-no-console.sh","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"uuid":"^14.0.0","langsmith":"^0.6.0"},"deprecated":"Versions <1.1.4 contained at least one residual reference to a prior dogfood product. v1.1.4 is the first version with a fully clean ship surface. Please upgrade: npm install pixelcheck@1.1.4","repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.6.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","@anthropic-ai/sdk":"^0.92.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.1.0_1777744490888_0.7349803748873931","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"pixelcheck","version":"1.1.1","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.1.1","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"c0877a14f2e4ec44172f052319cccc2ad27a31a2","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.1.1.tgz","fileCount":368,"integrity":"sha512-87MvvzgXpJBNecIxe6CM4GQ8LfZ2PifBf0jM/at6MYAHswWX3I/Bb+lWy2wMMLRFbfTFaUKqlZF4qZxPV6S1dQ==","signatures":[{"sig":"MEUCIQCF7SBG4NmUOMFfIlfCaQRa6jqDQIrgt1cy6YY1gcsR1QIgLliJB87xu2FDCyUiE4XTCBWE3ujfvOpNa669bJPBWzI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2696744},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=8.0.0","node":">=18.0.0"},"gitHead":"ff79cea7fbd5ec39e1ea175882d4816d415e9762","scripts":{"sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","lint:no-console":"bash scripts/check-no-console.sh","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"uuid":"^14.0.0","langsmith":"^0.6.0"},"deprecated":"Versions <1.1.4 contained at least one residual reference to a prior dogfood product. v1.1.4 is the first version with a fully clean ship surface. Please upgrade: npm install pixelcheck@1.1.4","repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.6.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","@anthropic-ai/sdk":"^0.92.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.1.1_1777745360822_0.4009758751611845","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"pixelcheck","version":"1.1.3","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.1.3","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"b2c07ba91056c4d89c6c5b3026f00311116f116d","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.1.3.tgz","fileCount":364,"integrity":"sha512-XBebo+FIEsa7kG/G5lOCH7AP0W3favoL46cLuxL+8v2zOEKenh7mW4VlgCCpr2Q17KEmgLmLXvJKrkiwngsTpg==","signatures":[{"sig":"MEYCIQCSoPWefdMct1F8WYVEGOlkXNvZOf1WxdRDSZyPfLnFlQIhAMbE+4UI1EFtSqACqpTYFt9+8tJofjBRQMxqTd00pFB1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2692524},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=8.0.0","node":">=18.0.0"},"gitHead":"50771f4536f222113d0c32874b648b39b0cb6744","scripts":{"sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","lint:no-console":"bash scripts/check-no-console.sh","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"uuid":"^14.0.0","langsmith":"^0.6.0"},"deprecated":"Versions <1.1.4 contained at least one residual reference to a prior dogfood product. v1.1.4 is the first version with a fully clean ship surface. Please upgrade: npm install pixelcheck@1.1.4","repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.6.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","@anthropic-ai/sdk":"^0.92.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.1.3_1777798981312_0.7356281260168811","host":"s3://npm-registry-packages-npm-production"}},"1.1.4":{"name":"pixelcheck","version":"1.1.4","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.1.4","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"af88213335d3faa6c11db21e447eda4e7201b701","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.1.4.tgz","fileCount":364,"integrity":"sha512-FKaN/xOUyumF/f16WYlYs4WEQHyGZ+AFxgaEFBldQbaHqvjXxNM2YY9oDbMp3umbx2IwLtCviT11fZs/pmR3bQ==","signatures":[{"sig":"MEYCIQDzchfiTynp+pb+saV/MgxpUT9rpBY/Uha0nOiAeK0j+wIhAKi2DjOM8+ASvlbnh7ZjO/yyiIJXYvTzc5xuDhiwcY2p","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2693512},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=8.0.0","node":">=18.0.0"},"gitHead":"728c430b70b7224555122ac2e2817351b076cc2a","scripts":{"sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","lint:no-console":"bash scripts/check-no-console.sh","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"uuid":"^14.0.0","langsmith":"^0.6.0"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.6.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","@anthropic-ai/sdk":"^0.92.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.1.4_1777800499521_0.6170373101719053","host":"s3://npm-registry-packages-npm-production"}},"1.1.5":{"name":"pixelcheck","version":"1.1.5","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.1.5","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"1dd37fc20459cb7ec00765ea69748fcae55b4e0b","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.1.5.tgz","fileCount":364,"integrity":"sha512-Z19pBtuU3nTct1yIN8euzVVi++jZs9MbFcEuYPqvVFduseIeFRsJOid7Jw9MULYxLImvKQBdur4ixrTkwhiPGQ==","signatures":[{"sig":"MEQCIFQuBjGS2Np5yThHDbZWGj/o5q2PCJ+b34SjcaW96ngFAiB0q7ch6hphr4uO781etpiu4hpVgbkW94JXLVrHP5x1Ig==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2694835},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=8.0.0","node":">=18.0.0"},"gitHead":"728c430b70b7224555122ac2e2817351b076cc2a","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","lint:no-console":"bash scripts/check-no-console.sh","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"uuid":"^14.0.0","langsmith":"^0.6.0"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.6.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","@anthropic-ai/sdk":"^0.92.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.1.5_1777906014625_0.7593416719193375","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"pixelcheck","version":"1.2.0","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.2.0","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"cc8624e0bb1055ae9ceb3a59a2dac3af9e1d590b","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.2.0.tgz","fileCount":407,"integrity":"sha512-M5Y2gj4cV7xu8f8GSA+QiOJ8bSMxVG6nDc+EOmnOCqG3Ss9WZUhfP6gjDfesgU/+8Wk/AtxDj/IobXZWVYvtGg==","signatures":[{"sig":"MEQCICdEI3gmrEhGdVnASuv4KqXDxJivurOOGI7S+o3XfVRFAiBm8pS9VqBKFuV+M7B/wz5Sp8/8+7kPzyVSVELRLUS1Vw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3602053},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=8.0.0","node":">=18.0.0"},"gitHead":"acdab8372cd53f1837cb4f3417a5b3a4635ff529","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","lint:no-console":"bash scripts/check-no-console.sh","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"uuid":"^14.0.0","langsmith":"^0.6.0","ip-address":"^10.2.0"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.6.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.2.0_1778081769522_0.409670682850112","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"pixelcheck","version":"1.2.1","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.2.1","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"63aec48dccab3c0399b91b05eeea6871317bdb5b","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.2.1.tgz","fileCount":410,"integrity":"sha512-AjloWY2SuKZq2ODNWLrC44t3pzV9RSSdDTqJYT9aoZWiBeHMub21Mz5Nhq8w8SM4kT2XRTQOojosP3TSjz6bsA==","signatures":[{"sig":"MEYCIQDNK1M/qqLvsHzER80tUsHMNw8y8JP+PkgTo+QKUxs4nQIhALpe2tUULobTA2taAl8xr3uZQvz2Wt2/SFOZpjebpC5O","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3614507},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=8.0.0","node":">=18.0.0"},"gitHead":"402ef967ad79b53098f4585a801c20fac32f5372","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","prepublishOnly":"npm run build && npm test","lint:no-console":"bash scripts/check-no-console.sh","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"uuid":"^14.0.0","langsmith":"^0.6.0","ip-address":"^10.2.0"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.6.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","eslint":"^10.3.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","typescript-eslint":"^8.59.2","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.2.1_1778577508093_0.7192315759448948","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"pixelcheck","version":"1.3.0","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.3.0","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"8d9c4dc45aea89d416af8476a0ad889462d5042f","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.3.0.tgz","fileCount":420,"integrity":"sha512-DfdaPFYgBsIAxDoXYmhYi95gLLoRMCu/1pEZ0qod/OlOh95tMBbPl2ztEKz7DLQ/LmixYlU6PX4Z4dnBDbIbFw==","signatures":[{"sig":"MEQCIHx8wxDS4totpLRmsVk9qBbR0sVGqLY7VP0W45YmAjNEAiAs4JphPgNEu5G5fEF0CBX2eZ9rokNVqeW7hXmR0VyDUw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/pixelcheck@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3743377},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=9.0.0","node":">=20.0.0"},"gitHead":"86405bef2d5ea73c8cb2551b9442a0cc6c901236","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"lint":"eslint src","sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","postinstall":"node scripts/postinstall.mjs","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","prepublishOnly":"npm run build && npm test","lint:no-console":"tsx scripts/check-no-console.ts","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","check:vendor-integrity":"tsx scripts/check-vendor-integrity.ts","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"uuid":"^14.0.0","langsmith":"^0.6.0","ip-address":"^10.2.0"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.34.5","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","playwright-core":"^1.49.0","@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","eslint":"^10.3.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","typescript-eslint":"^8.59.2","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.3.0_1780413062251_0.6400564038139325","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"pixelcheck","version":"1.4.0","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.4.0","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"3c646ff7f1ce17464f93405580fa1db0b2045332","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.4.0.tgz","fileCount":421,"integrity":"sha512-A48jr5dFKEETHTT6j8kMFKbxaBrRedwKfxwRzULYB7jVLMR2GIwesK8OQIwdUzmn/qshNRc8zPWMIPbdYaQWpQ==","signatures":[{"sig":"MEYCIQChMIdws+GAR/pZdOYqGqP05jvZbQaNXwB0+U9JzjR8VgIhAPnmYfz9I0NY0aZmnCkmw/rqFxO1WCTut79AZdFZz9Bm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/pixelcheck@1.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3782970},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=9.0.0","node":">=20.0.0"},"gitHead":"9e64ad20f6d4c58243554c26d4ac4c23591cd3a4","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"lint":"eslint src","sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","postinstall":"node scripts/postinstall.mjs","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","prepublishOnly":"npm run build && npm test","lint:no-console":"tsx scripts/check-no-console.ts","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","check:vendor-integrity":"tsx scripts/check-vendor-integrity.ts","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"hono":"^4.12.21","uuid":"^14.0.0","langsmith":"^0.6.0","ip-address":"^10.2.0","@hono/node-server":"^2.0.9"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.35.3","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","playwright-core":"^1.49.0","@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","eslint":"^10.3.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","typescript-eslint":"^8.59.2","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.4.0_1785045368339_0.26709381405452093","host":"s3://npm-registry-packages-npm-production"}},"1.4.1":{"name":"pixelcheck","version":"1.4.1","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.4.1","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"56035579c548a5e35780828e7bb31814e108b275","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.4.1.tgz","fileCount":421,"integrity":"sha512-JcH23KlmqUpch11p/Uxs1hjOB8lBsLssz2hRRqCRTGOORklidAdmLaRnXVzkAKc+frDQebJvytB1GkADZj6wSA==","signatures":[{"sig":"MEUCIEbgmd5l27rrz/ZohKwdvfrl+MyNeICbZNWmOIlT273VAiEAso/QLowW5arE3jPZnBjwA9wycADQ9EFJXPEG5AqyCcY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/pixelcheck@1.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3776996},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=9.0.0","node":">=20.0.0"},"gitHead":"7e717eb4d537a05fb21d003c3ccd6f47fb46e0dd","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"lint":"eslint src","sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && npm run lint:english-only && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","postinstall":"node scripts/postinstall.mjs","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","prepublishOnly":"npm run build && npm test","lint:no-console":"tsx scripts/check-no-console.ts","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","lint:english-only":"tsx scripts/check-english-only.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","check:vendor-integrity":"tsx scripts/check-vendor-integrity.ts","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"hono":"^4.12.21","uuid":"^14.0.0","langsmith":"^0.6.0","ip-address":"^10.2.0","@hono/node-server":"^2.0.9"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.35.3","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","playwright-core":"^1.49.0","@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","eslint":"^10.3.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","typescript-eslint":"^8.59.2","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.4.1_1785120494447_0.4857582097728068","host":"s3://npm-registry-packages-npm-production"}},"1.4.2":{"name":"pixelcheck","version":"1.4.2","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.4.2","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"be14b60acb123a74aeaa672440add625692937d4","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.4.2.tgz","fileCount":421,"integrity":"sha512-H7/h8kjoEC9HypL3GODDGnepEJNbGO46kc0HJnBZIN8AmhJP43XJkTmC1rtjgHyDZU8H5mHTVxnXZDh2UKY7LQ==","signatures":[{"sig":"MEUCIAe0Hw7QDYrDxOnSpmtINsY8xXXhNJO5RS8kEeV1jymGAiEA3bcGdrGF1C3TnZOuxdPjhFq5qjnKLlPbVUDOkBIuYtY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/pixelcheck@1.4.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":3776976},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=9.0.0","node":">=20.0.0"},"gitHead":"7bd6a67ce8e0ea9ef8a27aa056245b9d5fd7c939","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"lint":"eslint src","sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && npm run lint:english-only && npm run lint:no-internal-refs && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","postinstall":"node scripts/postinstall.mjs","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","prepublishOnly":"npm run build && npm test","lint:no-console":"tsx scripts/check-no-console.ts","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","lint:english-only":"tsx scripts/check-english-only.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","lint:no-internal-refs":"tsx scripts/check-no-internal-refs.ts","check:vendor-integrity":"tsx scripts/check-vendor-integrity.ts","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"hono":"^4.12.21","uuid":"^14.0.0","langsmith":"^0.6.0","ip-address":"^10.2.0","@hono/node-server":"^2.0.9"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"10.8.2","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.35.3","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","playwright-core":"^1.49.0","@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","eslint":"^10.3.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","typescript-eslint":"^8.59.2","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.4.2_1785142232306_0.6802513448472247","host":"s3://npm-registry-packages-npm-production"}},"1.4.3":{"name":"pixelcheck","version":"1.4.3","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.4.3","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"000c029ff0d114d19c46e2e2a1a133c2a9a9bf49","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.4.3.tgz","fileCount":302,"integrity":"sha512-c3s0Cis/hn1S3tfjBUFiwWQ40a6hDQVvD2Y32Gi37OOgdQgP6K3aK7BlsJ3uAYRmQky/VY53bVfhQ/g+9qtmPQ==","signatures":[{"sig":"MEUCIFyGzwBbPe0lDqS8J7ikHt389Yp/JqlfNrriJ7RMeaBpAiEAsxHPtbdLuni4bEBcJwgpPkIlzCiod/qA6rS9QkrbSUI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/pixelcheck@1.4.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2598853},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=9.0.0","node":">=20.0.0"},"gitHead":"12cf06cb7562966c53fc0496eac8dd16c77f7cfb","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"lint":"eslint src","sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && npm run lint:english-only && npm run lint:no-internal-refs && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc --removeComments --declaration false && tsc --emitDeclarationOnly","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","postinstall":"node scripts/postinstall.mjs","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","prepublishOnly":"npm run build && npm test","lint:no-console":"tsx scripts/check-no-console.ts","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","lint:english-only":"tsx scripts/check-english-only.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","lint:no-internal-refs":"tsx scripts/check-no-internal-refs.ts","check:vendor-integrity":"tsx scripts/check-vendor-integrity.ts","test:integration:playwright":"playwright test"},"_npmUser":{"name":"waynetaylor","email":"wayne@mysixbox.com"},"overrides":{"hono":"^4.12.21","uuid":"^14.0.0","langsmith":"^0.6.0","ip-address":"^10.2.0","@hono/node-server":"^2.0.9"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.18.0","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.35.3","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","playwright-core":"^1.49.0","@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","eslint":"^10.3.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","typescript-eslint":"^8.59.2","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.4.3_1785164083265_0.1455213691841839","host":"s3://npm-registry-packages-npm-production"}},"1.4.4":{"name":"pixelcheck","version":"1.4.4","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@1.4.4","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"670c887d22b4f09870ef4c52339f616bdab57965","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-1.4.4.tgz","fileCount":303,"integrity":"sha512-TeZrznTt7vdxmwJ4AR3FBCyjnXgjH3NKjVNSNrJejocFQf1oCQQuoHfcke/osEP2o1uXZ37R4bPjrYuWDxnyxw==","signatures":[{"sig":"MEYCIQCQzs92kB1S7H01N26amBQnKZixby2/yJYt3ptdaZmADAIhAMBVSY99Zss/j7xbj4OXkAv7boG1CEVifGcu+A7q+HQc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/pixelcheck@1.4.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2602315},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=9.0.0","node":">=20.0.0"},"gitHead":"b26a7ec4dbcdb4dc0af82b5788eae4f87a422645","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"lint":"eslint src","sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && npm run lint:english-only && npm run lint:no-internal-refs && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc --removeComments --declaration false && tsc --emitDeclarationOnly && node scripts/chmod-bins.mjs","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","postinstall":"node scripts/postinstall.mjs","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","prepublishOnly":"npm run build && npm test","lint:no-console":"tsx scripts/check-no-console.ts","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:integration":"vitest run --config vitest.integration.config.ts","lint:english-only":"tsx scripts/check-english-only.ts","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","lint:no-internal-refs":"tsx scripts/check-no-internal-refs.ts","check:vendor-integrity":"tsx scripts/check-vendor-integrity.ts","test:integration:playwright":"playwright test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:55718a59-280f-4679-ae79-75ff972e4caf"}},"overrides":{"hono":"^4.12.21","uuid":"^14.0.0","langsmith":"^0.6.0","ip-address":"^10.2.0","@hono/node-server":"^2.0.9"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.18.0","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.35.3","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"^12.9.0","playwright-core":"^1.49.0","@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","eslint":"^10.3.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","typescript-eslint":"^8.59.2","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^4.2.1"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_1.4.4_1785300223200_0.9879838161484269","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"pixelcheck","version":"2.0.0","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","_id":"pixelcheck@2.0.0","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"homepage":"https://github.com/xcodethink/pixelcheck#readme","bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"os":["darwin","linux","win32"],"bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"cpu":["x64","arm64"],"dist":{"shasum":"bfe0cf614c687dadaf5e08b5d2d604358d6ac4e6","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-2.0.0.tgz","fileCount":307,"integrity":"sha512-dAeOeUXXeMqJ1OuIW6TnkaGz+BM9WZ6RMr6wOL+a3UZq7KwDHQNxzAbD9nwyRrtwV4kqP8le0ZFKGvGiHYcOMA==","signatures":[{"sig":"MEUCIDPsN3N8V4S3CQfCpNlfO+D72z7A6q/4Uu1xfU/bDokpAiEAsDqrrXX5iI4sLcsVx3h9GZzd2x7AiFiUihi27V0zMXw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/pixelcheck@2.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2667491},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"npm":">=9.0.0","node":">=22.0.0"},"gitHead":"2f2fe8fe92520fb189ee9ccc6dc3ed58876b9948","mcpName":"io.github.xcodethink/pixelcheck","scripts":{"lint":"eslint src","sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","test":"npm run lint:no-console && npm run lint:english-only && npm run lint:no-internal-refs && npm run typecheck:scripts && vitest run","audit":"tsx src/cli.ts","bench":"vitest bench --run --outputJson=docs/perf-current.json","build":"tsc --removeComments --declaration false && tsc --emitDeclarationOnly && node scripts/chmod-bins.mjs","clean":"rm -rf dist sbom.json docs/api","schemas":"tsx scripts/export-result-schemas.ts","docs:api":"typedoc","typecheck":"tsc --noEmit","test:watch":"vitest","bench:check":"tsx scripts/check-perf.ts","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","postinstall":"node scripts/postinstall.mjs","sync:vendor":"bash scripts/sync-vendor.sh","bench:update":"tsx scripts/check-perf.ts --update-baseline","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","test:coverage":"vitest run --coverage","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","prepublishOnly":"npm run build && npm test","compare:critics":"tsx scripts/compare-critic-models.ts","lint:no-console":"tsx scripts/check-no-console.ts","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","lint:report-a11y":"tsx scripts/check-report-a11y.ts","test:integration":"vitest run --config vitest.integration.config.ts","lint:english-only":"tsx scripts/check-english-only.ts","measure:injection":"tsx scripts/measure-injection-asr.ts","typecheck:scripts":"tsc --noEmit -p tsconfig.scripts.json","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","lint:no-internal-refs":"tsx scripts/check-no-internal-refs.ts","check:vendor-integrity":"tsx scripts/check-vendor-integrity.ts","test:integration:playwright":"playwright test && npm run lint:report-a11y"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:55718a59-280f-4679-ae79-75ff972e4caf"}},"overrides":{"hono":"^4.12.34","uuid":"^14.0.0","fast-uri":"^3.1.5","langsmith":"^0.6.0","ip-address":"^10.2.0","@hono/node-server":"^2.0.9"},"repository":{"url":"git+https://github.com/xcodethink/pixelcheck.git","type":"git"},"_npmVersion":"11.19.0","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"ws":"^8.20.0","ora":"^9.4.0","zod":"^3.25.76","pino":"^10.3.1","yaml":"^2.6.0","chalk":"^5.3.0","sharp":"^0.35.3","dotenv":"^17.4.2","p-limit":"^7.3.0","axe-core":"^4.11.4","commander":"^14.0.3","odiff-bin":"^4.3.8","playwright":"^1.49.0","pino-pretty":"^13.1.3","better-sqlite3":"~12.11.1","playwright-core":"^1.49.0","@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.19.0","nock":"^14.0.14","eslint":"^10.3.0","vitest":"^4.1.4","typedoc":"^0.28.19","@types/ws":"^8.18.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^22.19.17","ajv-formats":"^3.0.1","license-checker":"^25.0.1","@playwright/test":"^1.59.1","typescript-eslint":"^8.59.2","zod-to-json-schema":"^3.25.2","@vitest/coverage-v8":"^4.1.5","@types/better-sqlite3":"^7.6.13","@cyclonedx/cyclonedx-npm":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pixelcheck_2.0.0_1785854823800_0.6873544832327099","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"pixelcheck","version":"2.1.0","mcpName":"io.github.xcodethink/pixelcheck","description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","type":"module","main":"dist/index.js","types":"dist/index.d.ts","bin":{"pixelcheck":"dist/cli.js","pixelcheck-mcp":"dist/mcp/server.js"},"engines":{"node":">=22.0.0","npm":">=9.0.0"},"os":["darwin","linux","win32"],"cpu":["x64","arm64"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/xcodethink/pixelcheck.git"},"bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"homepage":"https://github.com/xcodethink/pixelcheck#readme","scripts":{"build":"tsc --removeComments --declaration false && tsc --emitDeclarationOnly && node scripts/chmod-bins.mjs","postinstall":"node scripts/postinstall.mjs","prepublishOnly":"npm run build && npm test","typecheck":"tsc --noEmit","audit":"tsx src/cli.ts","test":"npm run lint:no-console && npm run lint:english-only && npm run lint:no-internal-refs && npm run typecheck:scripts && vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","test:coverage:check":"vitest run --coverage --coverage.thresholdAutoUpdate=false","test:integration":"vitest run --config vitest.integration.config.ts","test:integration:playwright":"playwright test && npm run lint:report-a11y","test:e2e:replay":"AUDIT_E2E_REPLAY=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","test:e2e:record":"AUDIT_E2E_RECORD=1 vitest run tests/integration/llm-cassettes.test.ts --no-file-parallelism","bench":"vitest bench --run --outputJson=docs/perf-current.json","bench:check":"tsx scripts/check-perf.ts","bench:update":"tsx scripts/check-perf.ts --update-baseline","measure:memory":"node --expose-gc --import tsx scripts/measure-memory.ts","lint:no-console":"tsx scripts/check-no-console.ts","lint:english-only":"tsx scripts/check-english-only.ts","lint:no-internal-refs":"tsx scripts/check-no-internal-refs.ts","lint":"eslint src","schemas":"tsx scripts/export-result-schemas.ts","license:check":"license-checker --production --onlyAllow \"MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;BSD;MPL-2.0;LGPL-3.0-or-later;Unlicense;CC-BY-3.0;CC-BY-4.0;CC0-1.0;0BSD;Apache*;(MIT OR WTFPL);(AFL-2.1 OR BSD-3-Clause);(BSD-2-Clause OR MIT OR Apache-2.0)\"","license:csv":"license-checker --production --csv --out docs/third-party-licenses.csv","sbom":"cyclonedx-npm --output-file sbom.json --omit dev --ignore-npm-errors","docs:api":"typedoc","sync:vendor":"bash scripts/sync-vendor.sh","check:vendor-drift":"tsx scripts/check-vendor-drift.ts","check:vendor-integrity":"tsx scripts/check-vendor-integrity.ts","clean":"rm -rf dist sbom.json docs/api","lint:report-a11y":"tsx scripts/check-report-a11y.ts","measure:injection":"tsx scripts/measure-injection-asr.ts","compare:critics":"tsx scripts/compare-critic-models.ts","typecheck:scripts":"tsc --noEmit -p tsconfig.scripts.json"},"keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"license":"MIT","dependencies":{"@anthropic-ai/sdk":"^0.94.0","@browserbasehq/stagehand":"^3.3.0","@modelcontextprotocol/sdk":"^1.29.0","axe-core":"^4.11.4","better-sqlite3":"~12.11.1","chalk":"^5.3.0","commander":"^14.0.3","dotenv":"^17.4.2","odiff-bin":"^4.3.8","ora":"^9.4.0","p-limit":"^7.3.0","pino":"^10.3.1","pino-pretty":"^13.1.3","playwright":"^1.49.0","playwright-core":"^1.49.0","sharp":"^0.35.3","ws":"^8.20.0","yaml":"^2.6.0","zod":"^3.25.76"},"overrides":{"langsmith":"^0.6.0","uuid":"^14.0.0","ip-address":"^10.2.0","hono":"^4.12.34","@hono/node-server":"^2.0.9","fast-uri":"^3.1.5"},"devDependencies":{"@cyclonedx/cyclonedx-npm":"^6.0.0","@eslint/js":"^10.0.1","@playwright/test":"^1.59.1","@types/better-sqlite3":"^7.6.13","@types/node":"^22.19.17","@types/ws":"^8.18.1","@vitest/coverage-v8":"^4.1.5","ajv":"^8.20.0","ajv-formats":"^3.0.1","eslint":"^10.3.0","license-checker":"^25.0.1","nock":"^14.0.14","tsx":"^4.19.0","typedoc":"^0.28.19","typescript":"^6.0.3","typescript-eslint":"^8.59.2","vitest":"^4.1.4","zod-to-json-schema":"^3.25.2"},"gitHead":"0aa3f471b94b1f7019c169acc5bbdd000ebd0e00","_id":"pixelcheck@2.1.0","_nodeVersion":"22.23.1","_npmVersion":"11.19.0","dist":{"integrity":"sha512-lHtBnnAbxBUtyl0G0pzbRuOzckyyoeW067k6pmBRz1NaiXtIKQA6yhqWNn8EuuAzgbS+I//ZdGEifD5y2VpyHQ==","shasum":"2809a6383e5e32579b8d014c0fc34ed7e11e44a1","tarball":"https://registry.npmjs.org/pixelcheck/-/pixelcheck-2.1.0.tgz","fileCount":307,"unpackedSize":2671923,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/pixelcheck@2.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBN0wiVfFSM65ynxxwZoYsFeLGlzFQLUHALnyCc8DqYsAiEA0MVfV9hkKyiKwvMO6ygOoLNNSkoRmG0Ig69AMlb77fI="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:55718a59-280f-4679-ae79-75ff972e4caf"}},"directories":{},"maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pixelcheck_2.1.0_1785859220517_0.7587926015571584"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-02T12:51:24.637Z","modified":"2026-08-04T16:00:21.148Z","1.0.0":"2026-05-02T12:51:24.989Z","1.0.1":"2026-05-02T14:16:37.569Z","1.1.0":"2026-05-02T17:54:51.079Z","1.1.1":"2026-05-02T18:09:21.027Z","1.1.3":"2026-05-03T09:03:01.532Z","1.1.4":"2026-05-03T09:28:19.696Z","1.1.5":"2026-05-04T14:46:54.850Z","1.2.0":"2026-05-06T15:36:09.751Z","1.2.1":"2026-05-12T09:18:28.277Z","1.3.0":"2026-06-02T15:11:02.487Z","1.4.0":"2026-07-26T05:56:08.513Z","1.4.1":"2026-07-27T02:48:14.626Z","1.4.2":"2026-07-27T08:50:32.471Z","1.4.3":"2026-07-27T14:54:43.453Z","1.4.4":"2026-07-29T04:43:43.385Z","2.0.0":"2026-08-04T14:47:04.014Z","2.1.0":"2026-08-04T16:00:20.796Z"},"bugs":{"url":"https://github.com/xcodethink/pixelcheck/issues"},"license":"MIT","homepage":"https://github.com/xcodethink/pixelcheck#readme","keywords":["mcp","mcp-server","ai-agent","browser-primitives","ai-browser","vendor-agnostic","local-first","playwright","stagehand","claude","computer-use","audit","ux"],"repository":{"type":"git","url":"git+https://github.com/xcodethink/pixelcheck.git"},"description":"MCP-first browser primitives for AI agents — real eyes and hands on the web. Local-first. Vendor-agnostic. Yours to own.","maintainers":[{"name":"waynetaylor","email":"wayne@mysixbox.com"}],"readme":"<h1 align=\"center\">PixelCheck</h1>\n\n<p align=\"center\">\n  <strong>Real eyes and hands for the AI agent that's writing your frontend.</strong>\n</p>\n\n<p align=\"center\">\n  Drop-in MCP server. Five browser primitives. Eighteen personas across fifteen countries.<br/>\n  Local-first &middot; Vendor-agnostic &middot; MIT-licensed &middot; Yours to own.\n</p>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/pixelcheck\"><img alt=\"npm\" src=\"https://img.shields.io/npm/v/pixelcheck?color=cb3837&label=npm&logo=npm&logoColor=white\"></a>\n  <a href=\"https://www.npmjs.com/package/pixelcheck\"><img alt=\"npm downloads\" src=\"https://img.shields.io/npm/dm/pixelcheck?color=cb3837&logo=npm&logoColor=white\"></a>\n  <a href=\"LICENSE\"><img alt=\"license\" src=\"https://img.shields.io/github/license/xcodethink/pixelcheck?color=3da639\"></a>\n  <a href=\"https://modelcontextprotocol.io\"><img alt=\"MCP\" src=\"https://img.shields.io/badge/MCP-compatible-4f46e5\"></a>\n  <a href=\"https://github.com/xcodethink/pixelcheck/actions/workflows/ci.yml\"><img alt=\"CI\" src=\"https://img.shields.io/github/actions/workflow/status/xcodethink/pixelcheck/ci.yml?branch=main&label=CI&logo=github\"></a>\n  <img alt=\"node\" src=\"https://img.shields.io/node/v/pixelcheck?color=339933&logo=node.js&logoColor=white\">\n  <img alt=\"typescript\" src=\"https://img.shields.io/github/languages/top/xcodethink/pixelcheck?color=3178c6&logo=typescript&logoColor=white\">\n  <a href=\"https://github.com/xcodethink/pixelcheck/releases/latest\"><img alt=\"release\" src=\"https://img.shields.io/github/v/release/xcodethink/pixelcheck?color=3178c6&logo=github\"></a>\n  <a href=\"https://github.com/xcodethink/pixelcheck/stargazers\"><img alt=\"stars\" src=\"https://img.shields.io/github/stars/xcodethink/pixelcheck?style=flat&color=ffd700\"></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#quick-start\"><b>Quick Start →</b></a>\n  &nbsp;&middot;&nbsp;\n  <a href=\"#primitives\">Primitives</a>\n  &nbsp;&middot;&nbsp;\n  <a href=\"#mcp-server\">MCP Server</a>\n  &nbsp;&middot;&nbsp;\n  <a href=\"#audit-preset\">Audit Preset</a>\n  &nbsp;&middot;&nbsp;\n  <a href=\"#why-not-e2e-tests\">Why Not E2E</a>\n  &nbsp;&middot;&nbsp;\n  <a href=\"CHANGELOG.md\">Changelog</a>\n</p>\n\n---\n\n> **If PixelCheck helps you, [give it a star](https://github.com/xcodethink/pixelcheck/stargazers) — it helps others discover the project.**\n\n---\n\n## Right now, you're a screenshotting middleman.\n\nYour AI agent is writing 80% of your frontend. It's fast. It's good at code. But it's blind.\n\n- **It writes a button.** You open Chrome to check it rendered right. Paste a screenshot back. Ask for the fix.\n- **It tweaks the OAuth flow.** You log in to verify it didn't silently break. Again. Sixth time this month.\n- **It updates the Japanese strings.** A user emails: \"half the page is in English.\" You didn't catch it.\n- **It rewrites checkout.** You walk through it on iPhone, Android, iPad just to *feel* whether step 3 is confusing.\n- **It changes the Arabic layout.** RTL didn't propagate. You don't notice for two days.\n\nYou become the bridge. The agent has thoughts. You have a browser. **The two never meet.** Hours of your week, every week, indefinitely.\n\n<a id=\"primitives\"></a>\n\n## PixelCheck is the bridge.\n\nA single MCP server. Five primitives. Drop it in once — your agent has eyes and hands.\n\n```\nsee(url, opts)              snapshot a page (DOM + screenshot + console + network)\nact(url, steps)             execute an action sequence (semantic + selector + Computer Use)\nextract(url, schema)        pull structured data matching a Zod / JSON schema\njudge(url, rubric)          score a page against a rubric (\"is this dark-pattern free?\")\ncompare(a, b, criteria)     A/B comparison of two URLs (incl. blind mode)\n```\n\nNow your agent navigates. Sees rendered HTML. Reads console errors. Clicks. Fills. Judges. Compares. **Without ever leaving its workflow** — drop into Claude Desktop, Cursor, Cline, Continue, Zed, or Claude Code via four lines in `~/.mcp.json`.\n\n```bash\nnpm install -g pixelcheck        # browser binary auto-installs on install\npixelcheck doctor                # verify environment (--fix self-heals)\npixelcheck-mcp                   # MCP server (stdio transport)\n```\n\n```jsonc\n// ~/.mcp.json\n{\n  \"mcpServers\": {\n    \"pixelcheck\": {\n      \"command\": \"pixelcheck-mcp\",\n      \"env\": { \"ANTHROPIC_API_KEY\": \"sk-ant-...\" }\n    }\n  }\n}\n```\n\nRestart your client. Your agent has eyes.\n\n## Three promises that aren't going anywhere.\n\n**Local-first.** PixelCheck runs entirely on your machine. The only outbound network destination is the LLM provider your agent already uses. Screenshots, DOMs, business flows, OAuth tokens, customer URLs — they stay yours. Zero telemetry. Zero remote storage. Zero SaaS sign-up. The audit data hits Anthropic only when the vision critic actively scores a screenshot, and you opt in once on first run.\n\n**Vendor-agnostic.** Works with Claude today; multi-provider abstraction (OpenAI, Gemini, Ollama-local) is on the v1.x roadmap and your agent will switch with one config flag. The reason is simple: AI tools that lock you to a single LLM provider die in 2026. PixelCheck is the antidote.\n\n**Yours to own.** MIT license. Source-available. No paid tier. No \"Pro\" upgrade path. No commercial fork waiting in the wings. The 1858-test, 29-ADR, 30-published-schema product in this repo *is* the entire product. There's no premium edition behind a sign-up wall — never was, never will be.\n\n---\n\n<a id=\"audit-preset\"></a>\n\n## The Audit Preset — when *you* want to be the user, not the bridge\n\nThe five primitives compose into something more powerful when you're the operator: PixelCheck bundles an **18-persona / 15-country audit preset** on top of the primitives — a CLI-first composition that runs \"eighteen real users review your product\" after every deployment.\n\nYou deploy. Tests pass. CI is green. But then:\n\n- A Japanese user opens your app and sees half-translated English strings mixed into the UI\n- A user on a budget Android phone in Nigeria waits 12 seconds for your hero image to load\n- Your OAuth login flow silently breaks — again — for the 6th time in 10 deployments\n- The Arabic version renders left-to-right, making the entire layout unusable\n- Your \"Trusted\" score badge shows green while the copy says \"stop interacting immediately\"\n\n**No E2E test catches these.** They test whether code runs. They don't test whether the product *works* for real humans in real contexts.\n\nThe audit preset launches real Chromium browsers as 18 different users from 17 countries, walks through your product's core flows, and delivers a verdict — like having a senior PM, QA engineer, and UX reviewer audit every deployment, in every language, on every device class.\n\n```bash\npixelcheck init projects/my-app --name \"My App\" --url \"https://myapp.com\"\npixelcheck run --project projects/my-app\n```\n\n**Output**: a structured report with per-step screenshots, video recordings, network logs, WCAG accessibility violations, and AI-scored ratings across 6 dimensions — served as JSON, HTML dashboard, or Markdown.\n\n## How It Works\n\nFor each **(persona x scenario)** combination:\n\n```\n 1. Launch Chromium with device-accurate fingerprint\n    (viewport, locale, timezone, UA, regional proxy)\n                        |\n 2. Execute scenario steps semantically via Stagehand 3.x\n    (\"click the sign-up button\" not \"click #btn-37\")\n                        |\n 3. 5-Layer Reliability Stack ensures 98%+ step success\n    Stability Gate -> LLM Rewrite -> Selector Discovery -> Auto Selector -> Computer Use\n                        |\n 4. Claude Vision Critic + axe-core score each checkpoint on 18 dimensions\n    completion | localization | visual_polish | trust_signals | accessibility | ...\n                        |\n 5. Critical steps escalate to Computer Use for pixel-level review\n                        |\n 6. Generate report: JSON + HTML dashboard + Markdown + video + HAR\n```\n\n## Why Not E2E Tests?\n\n| | Traditional E2E | PixelCheck (audit preset) |\n|---|---|---|\n| **What it tests** | Code logic | Product experience |\n| **Decision making** | Hardcoded selectors | AI reads the page like a human |\n| **Assertion style** | `expect(text).toBe(\"Welcome\")` | *\"As a Japanese free-tier user, is this CTA clear and fully localized?\"* |\n| **When UI changes** | Selectors break, tests fail | Semantic instructions adapt automatically |\n| **Failure output** | Stack trace | Screenshots + video + 6-dimension score + specific UX issues |\n| **What it catches** | Functional bugs | i18n gaps, UX friction, visual regressions, trust issues, accessibility violations, cultural mismatches |\n\n**PixelCheck's audit preset is not a replacement for E2E tests.** It's what runs *after* them — the layer between \"code works\" and \"product is good.\"\n\n## Compared to existing tools\n\n| | **PixelCheck** | Playwright | Cypress | Stagehand | Browserbase |\n|---|---|---|---|---|---|\n| **MCP server out of the box** | ✅ | ❌ | ❌ | ❌ | ❌ |\n| **Browser primitives an AI agent can call** | 5 (see / act / extract / judge / compare) | n/a (low-level page API) | n/a | 3 (act / extract / observe) | n/a |\n| **AI vision (judge / critique)** | ✅ via Anthropic | ❌ | ❌ | ❌ (action-only) | ❌ |\n| **Built-in personas** | 18 across 15 countries | ❌ | ❌ | ❌ | ❌ |\n| **Localised report (5 languages)** | ✅ | ❌ | ❌ | ❌ | ❌ |\n| **WCAG 2.x audit + SARIF export** | ✅ (axe-core + GitHub Code Scanning ready) | manual via plugins | manual via plugins | ❌ | ❌ |\n| **Local-first by default** | ✅ (your machine, your API key) | ✅ | ✅ | ✅ (or Browserbase) | ❌ (cloud-only) |\n| **Vendor lock-in** | none (MIT, no SaaS) | none | none | optional Browserbase | full (paid SaaS) |\n| **LLM provider** | swap any (Anthropic default; primitives are vendor-agnostic) | n/a | n/a | swap any | n/a |\n| **Open source** | ✅ MIT | ✅ Apache 2.0 | ✅ MIT | ✅ MIT | partial |\n\n**TL;DR**: Playwright / Cypress are deterministic browser drivers — you tell them exactly what to click. Stagehand wraps Playwright with natural-language `act` / `extract` so an agent can drive a browser. PixelCheck is the next layer up: an MCP-shaped surface that gives any AI agent vision (`see` / `judge` / `compare`) on top of action (`act` / `extract`), with audit presets composed across personas. Use Playwright for unit-style tests; use Stagehand if you only need an agent to fill forms; use PixelCheck when the agent needs to *evaluate* a UI, not just operate it.\n\n## Personas\n\n18 built-in personas covering real-world user diversity. The **Subscriber Tier** column is the persona's subscription level *in the SaaS you're auditing* (Free user / Pro subscriber / Power-user / enterprise) — used so PixelCheck can audit your product's tiered features (paywalls, upsells, gated UI, Pro-only flows). **PixelCheck itself is MIT-licensed and 100% free with no paid tier or commercial fork.**\n\n| Persona | Country | Language | Device | Subscriber Tier (in your app) |\n|---|---|---|---|---|\n| US college student | US | English | iPhone 14 | Free |\n| Tokyo housewife | JP | Japanese | MacBook Pro | Pro |\n| Berlin security analyst | DE | German | iPad Pro | Power |\n| Shanghai student | CN | Chinese | Xiaomi Android | Free |\n| Sao Paulo freelancer | BR | Portuguese | Desktop | Free |\n| Riyadh businessman | SA | Arabic (RTL) | iPhone 15 Pro | Pro |\n| Mumbai office worker | IN | Hindi | Budget Android | Free |\n| Seoul designer | KR | Korean | QHD Desktop | Pro |\n| Hanoi student | VN | Vietnamese | Android | Free |\n| Moscow engineer | RU | Russian (Cyrillic) | Windows Desktop | Free |\n| Lagos entrepreneur | NG | English | Budget Tecno | Free |\n| Mexico City teacher | MX | Spanish (LATAM) | Android | Free |\n| Jakarta gig worker | ID | Bahasa Indonesia | Android | Free |\n| US retired teacher (72yo) | US | English | iPad | Free |\n| London security analyst | UK | English | Desktop | Power |\n| Paris marketing manager | FR | French | iPhone | Free |\n| Bangkok student | TH | Thai | iPhone SE | Free |\n| Taipei engineer | TW | Traditional Chinese | iPad | Pro |\n\nEach persona includes a **mental model** (who they are, what they expect) and **critical concerns** (what would make them lose trust). The AI reviewer judges your product *through their eyes*.\n\n**6 script systems**: Latin, CJK, Arabic (RTL), Cyrillic, Devanagari, Thai.\n\n## Scenarios Are Declarative YAML\n\nNo code required. Describe what a user does, not how to click:\n\n```yaml\nid: signup-flow\nname: New User Signup\npriority: P0\nsteps:\n  - id: open-home\n    type: visit\n    url: https://myapp.com/${persona.url_locale}\n\n  - id: click-signup\n    type: act\n    instruction: Click the sign-up or get-started button\n\n  - id: check-language\n    type: assert_visual\n    instruction: |\n      Is all visible text in ${persona.language}?\n      Flag any English strings outside of brand names.\n\n  - id: complete-oauth\n    type: act\n    instruction: Sign in with Google\n\n  - id: verify-email\n    type: check_email\n    subject_contains: \"welcome\"\n    timeout: 60000\n\n  - id: a11y-check\n    type: assert_a11y\n    standard: wcag2aa          # axe-core WCAG analysis\n    exclude: [\".cookie-banner\"]\n\n  - id: rate-onboarding\n    type: assert_visual\n    critical_review: true    # escalates to Computer Use\n    instruction: |\n      Rate the post-signup experience. Is the value proposition\n      clear within 10 seconds? Is the first action obvious?\n```\n\n**12 step types**: `visit`, `act`, `extract`, `observe`, `wait_for`, `assert_visual`, `assert_dom`, `assert_a11y`, `check_email`, `screenshot`, `computer_use`, `custom`\n\n## 5-Layer Reliability Stack\n\nAI-driven browsers are flaky (~75% baseline). We engineered that away:\n\n```\nLayer 1: Page Stability Gate                              +10%  (zero cost)\n         Wait for network idle + DOM stable + framework hydration\n                            |\nLayer 2: LLM Rewrite + Local Mutation                     +7%   (~$0.001/call)\n         Haiku rewrites failed instructions using DOM context;\n         local rules rephrase/decompose/specify as fallback\n                            |\nLayer 3a: Selector Hint                                   +3%   (zero cost)\n          Optional CSS selector fallback (manual or YAML-defined)\n                            |\nLayer 3b: Auto Selector Discovery                         +3%   (zero cost)\n          Stagehand observe() extracts candidate selectors automatically\n                            |\nLayer 4: Computer Use Fallback                            +2-4% ($0.01-0.15/call)\n         Claude sees the actual pixels and operates the browser directly\n         (Sonnet for non-critical steps, Opus for critical reviews)\n```\n\nTarget: **98-99% step success rate** across all persona/scenario combinations.\n\nEach step records which layer succeeded via `execution_method`, giving you a reliability breakdown per run.\n\n## Reports\n\nEvery audit produces a full evidence package:\n\n```\nreports/2026-04-11_post-deploy/\n |-- audit.json              # Machine-readable, all scores and issues\n |-- audit.html              # Dark-theme dashboard with trend sparklines\n |-- audit-explorer.html     # Filterable SPA view of every (scenario × persona) — open with ?lang=zh-CN/ja/es/de for localised UI chrome\n |-- audit.pdf               # Stakeholder-facing summary (A4, 12pt, vector text)\n |-- summary.md              # Terminal-friendly overview\n |-- jp-japanese-pro-desktop__signup-flow/\n      |-- 01-open_home.png          # Timestamped screenshot\n      |-- 02-check_language.png     # + SHA-256 hash for each\n      |-- network.har               # Full network log\n      |-- console.log               # Browser console errors\n      |-- video/*.webm              # Session recording\n```\n\n`audit.json` and every MCP tool response carries a top-level `schema_version` field (SemVer). The contract is documented in [docs/contracts/RESULT_SCHEMA.md](./docs/contracts/RESULT_SCHEMA.md); machine-readable JSON Schemas live in [docs/schemas/](./docs/schemas/) and can be regenerated with `npm run schemas`.\n\n### WCAG compliance reporting\n\nThe `assert_a11y` scenario step runs [axe-core](https://github.com/dequelabs/axe-core) to detect accessibility violations. As of v1, every violation carries structured WCAG attribution that flows through to all stakeholder reports:\n\n- **PDF report** — a \"WCAG Compliance Summary\" section grouped by conformance level (A / AA / AAA), by the four WCAG principles (Perceivable / Operable / Understandable / Robust), and a top-violated-criteria table with deep links to the W3C Understanding documents.\n- **SARIF (GitHub Code Scanning / GitLab SAST)** — per-criterion ruleIds like `wcag/1-4-3`, `wcag/2-1-1`. Filter by W3C clause directly in the Security tab. Each rule's detail panel shows \"WCAG 1.4.3 Contrast (Minimum) (Level AA)\" with a link to the W3C spec.\n- **audit.json** — every accessibility issue gets `wcag_level` and `wcag_criterion` fields alongside the existing `description` / `recommendation`.\n\nCatalog covers WCAG 2.1 (the production-deployed standard) plus the 9 net-new success criteria added in WCAG 2.2 (e.g. 2.4.11 Focus Not Obscured, 2.5.8 Target Size). Compliance teams reading reports in zh-CN / ja / es / de see the section headings translated; SC names and id numbers (1.4.3, 2.1.1) stay canonical for compliance-document consistency.\n\nUse case — answering an RFP that asks \"Are you WCAG 2.1 AA compliant?\":\n\n```bash\npixelcheck run --project myapp                                    # writes audit.pdf + audit.sarif\n# Open audit.pdf → \"WCAG Compliance Summary\" section shows A / AA / AAA counts\n# Or upload audit.sarif via github/codeql-action/upload-sarif → grouped under wcag/* ruleIds\n```\n\nSee [ADR-024](docs/decisions/ADR-024-wcag-clause-grouping.md) for the full design.\n\n### Localised reports\n\nStakeholder reports (PDF / trends dashboard / PR diff Markdown / PR diff HTML) emit in the language of your audience. v1 supports 5 locales:\n\n| Code | Language | Used for |\n|---|---|---|\n| `en` | English (default) | Baseline |\n| `zh-CN` | Simplified Chinese | China-market teams |\n| `ja` | Japanese | Japan-market product orgs |\n| `es` | Spanish | Spain + Latin America |\n| `de` | German | DACH-region enterprises |\n\n```bash\npixelcheck run --project myapp --locale ja          # Japanese PDF + reports\npixelcheck trends --project myapp --locale zh-CN     # Chinese trends dashboard\npixelcheck diff <a> <b> --format markdown --locale es  # Spanish PR comment\n```\n\nOr pin a default in `config.yaml`:\n```yaml\nproject_name: myapp\nbase_url: https://myapp.com\ndefault_locale: ja    # any audit run on this project defaults to ja\n```\n\nWhat's translated: report skeleton — section titles, table headers, status / severity badges, disclaimer prose. What's NOT translated: PixelCheck's findings themselves (those come from the LLM in whatever language you asked Claude for) and numeric values / dates / run IDs. See [ADR-023](docs/decisions/ADR-023-report-localisation.md) for the full design.\n\n**Translations reviewed by**: machine-assisted draft pending native-speaker review. We track reviewer credits publicly — see [docs/translation-review-template.md](docs/translation-review-template.md) and the [translation-review issue template](.github/ISSUE_TEMPLATE/translation-review.yml). Confirmed reviewers will be listed below as the v1.x review pass completes.\n\n| Locale | Reviewer | Date | Corrections applied |\n|---|---|---|---|\n| `en` | (source — no review needed) | — | — |\n| `zh-CN` | _pending_ | _pending_ | _pending_ |\n| `ja` | _pending_ | _pending_ | _pending_ |\n| `es` | _pending_ | _pending_ | _pending_ |\n| `de` | _pending_ | _pending_ | _pending_ |\n\n### PDF report (audit.pdf)\n\nA 4-section A4 portrait PDF aimed at the layer of decision-makers above engineering — PMs, executives, customers, sales / CS reps. The format every email client renders inline, every slide deck embeds, every phone opens.\n\n| Section | Contents |\n|---|---|\n| Cover | Project + URL + run date + colour-coded overall score (green ≥ 8, amber 5–8, red < 5) + 7-counter summary card |\n| Top findings | Severity-sorted (critical → high → medium → low), capped at 5; each cites scenario × persona context + recommendation |\n| Scenario results | One block per (scenario × persona): status badge, score + cost, per-dimension table, all issues |\n| Methodology | How the audit works, persona list, scenario list, calibration disclaimer, run id for archival |\n\nVector text (selectable / searchable / accessible) — not a screenshot of HTML. No screenshots embedded so the file stays under ~1 MB and emailable; for visual evidence, the recipient opens `audit-explorer.html` (cited in the methodology disclaimer).\n\nDefault: ON every run. Pass `--no-pdf` to skip during fast local iteration. See [ADR-020](docs/decisions/ADR-020-pdf-stakeholder-report.md) for the full design.\n\n### Historical Trends\n\nScores are tracked in a local SQLite database. Three ways to look at history:\n\n```bash\npixelcheck history                    # Terminal table of recent runs with scores\npixelcheck diff run_0412 run_0411     # Score deltas, new/resolved issues\npixelcheck trends                     # Full HTML dashboard with 5 charts (writes <reports>/trends.html)\n```\n\n`pixelcheck trends` reads `<reports>/history.db` and writes a standalone HTML dashboard answering \"did our UX get better or worse?\" Five inline-SVG charts (no Chart.js / external CDN — opens behind any firewall, emails / prints / archives cleanly):\n\n| Chart | Answer it gives |\n|---|---|\n| Overall score line | Trending up or down? |\n| Pass / Warn / Fail stacked bars | Consistent or flaky? |\n| Issues over time (total + critical) | Where are the regression hot spots? |\n| Cost over time | Is efficiency drifting? |\n| Per-dimension multi-line | Which scoring dimension is the cause? |\n\nPlus six summary cards at the top (latest score, mean last 7, mean last 30, total cost, total issues, total critical issues) and a recent-runs table for navigation. See [ADR-021](docs/decisions/ADR-021-trends-dashboard.md) for the full design.\n\n```bash\npixelcheck trends --project myapp -n 90 --dashboard reports/trends.html\n```\n\nThe per-run `audit.html` also includes inline sparkline charts for at-a-glance trends within that single report.\n\n### Quality Gate\n\nFail your CI build if the experience drops below your bar:\n\n```bash\npixelcheck run --project projects/my-app --min-score 7.5\n# Exit code 1 if overall score < 7.5\n```\n\n## Quick Start\n\n### 1. Install\n\n```bash\nnpm install pixelcheck\n```\n\nThe browser binary pixelcheck needs (Chrome Headless Shell) is fetched\nautomatically by a `postinstall` step. If that was skipped — CI,\n`--ignore-scripts`, an offline box, or `PIXELCHECK_SKIP_BROWSER_DOWNLOAD=1` —\nfetch it on demand with:\n\n```bash\nnpx pixelcheck install            # headless audits (default)\nnpx pixelcheck install --headed   # also fetch full Chromium for --headed runs\n```\n\nYou never need a bare `npx playwright install` — pixelcheck installs the exact\nbrowser revision it launches (a bare install can pull a mismatched revision).\nA missing browser also self-heals on the first `run`/`explore`, and\n`pixelcheck doctor --fix` downloads it directly.\n\n> For corporate proxy / Alpine Linux / Docker / air-gapped environments,\n> see [docs/INSTALLATION.md](docs/INSTALLATION.md).\n\n### 2. Verify your environment\n\n```bash\nnpx pixelcheck doctor\n```\n\nReports Node version, API key, config / scenarios / personas, network\nproxy, and api.anthropic.com reachability. Exits 0 when ready, 1 when\nany check fails — useful in CI scripts to fail-fast before running an audit.\n\nAdd `--verbose` for diagnostic detail, `--skip-network` for offline /\nair-gapped environments.\n\n### 3. Set up a project (interactive or scripted)\n\n**Interactive wizard** (recommended for first-time users):\n\n```bash\nnpx pixelcheck init\n# Walks you through project name, base URL, sample scenario, and runs\n# `doctor` at the end to confirm setup.\n```\n\n**Non-interactive** (CI / scripted):\n\n```bash\nnpx pixelcheck init my-project --name acme-shop --url https://acme.example.com\n```\n\nEither path scaffolds:\n- `config.yaml` (project name + base URL + model defaults + budget)\n- `scenarios/00-smoke.yaml` (starter visual + a11y check)\n\n### 4. Set your API key\n\n```bash\nexport ANTHROPIC_API_KEY=sk-ant-...\n```\n\nGet a key at [console.anthropic.com](https://console.anthropic.com).\nThe wizard above tells you when this is missing; `pixelcheck doctor`\nre-checks it any time.\n\n### 5. Create your first audit\n\n```bash\nnpx pixelcheck init projects/my-app --name \"My App\" --url \"https://myapp.com\"\n```\n\nThis generates a project directory with a config file and a starter scenario. Edit the scenario to match your app's flows.\n\n### 6. Run\n\n```bash\n# Dry run — validate config, print the persona x scenario matrix\nnpx pixelcheck run --project projects/my-app --dry-run\n\n# Full audit\nnpx pixelcheck run --project projects/my-app\n\n# Debug mode — visible browser\nnpx pixelcheck run --project projects/my-app --headed\n\n# Single persona\nnpx pixelcheck run --project projects/my-app --persona jp-japanese-pro-desktop\n```\n\n## CI Integration\n\nTrigger an audit after every deployment:\n\n```yaml\n# .github/workflows/deploy.yml\naudit-after-deploy:\n  needs: [deploy]\n  runs-on: ubuntu-latest\n  steps:\n    - uses: actions/checkout@v4\n    # CI sets CI=true, which skips the auto browser-download; fetch it explicitly.\n    - run: npm install pixelcheck && npx pixelcheck install\n    - run: npx pixelcheck run --project .audit --min-score 7.0\n      env:\n        ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}\n    - uses: actions/upload-artifact@v4\n      if: always()\n      with:\n        name: audit-report\n        path: reports/\n```\n\nOr dispatch to a central PixelCheck repo that audits all your projects:\n\n```yaml\n    - run: |\n        gh workflow run post-deploy-audit.yml \\\n          --repo your-org/pixelcheck \\\n          --field project=\"my-app\"\n      env:\n        GH_TOKEN: ${{ secrets.GH_PAT }}\n```\n\nExit codes: `0` = pass, `1` = fail, `2` = warn.\n\n### CI output formats\n\nWhen PixelCheck detects a CI environment (`CI=true`, `GITHUB_ACTIONS=true`, `GITLAB_CI=true`, `CIRCLECI=true`, `TF_BUILD=True`, or `JENKINS_URL`), it automatically emits four standard formats alongside `audit.json`/`audit.html`:\n\n| File | Format | Consumed by |\n|---|---|---|\n| `junit.xml` | JUnit XML | Jenkins, GitLab CI, Azure DevOps, CircleCI |\n| `audit.sarif` | SARIF 2.1.0 | GitHub Code Scanning, GitLab SAST |\n| `audit.jsonl` | JSON Lines (one record per line) | jq, log aggregators, custom dashboards |\n| `github-annotations.txt` | GHA workflow commands | GitHub Actions inline PR annotations |\n\nInside GitHub Actions the workflow-command lines are also streamed to stderr so issues attach inline to PR diffs without a separate annotation step.\n\nOverride behaviour explicitly:\n- `--ci-format auto` — default; emit all 4 in CI, none on developer laptop\n- `--ci-format all` — force-emit all 4 regardless of environment\n- `--ci-format none` — skip CI formats\n- `--ci-format junit,sarif` — comma-separated subset\n\nSeverity mapping: `critical`/`high` → SARIF `error` / GHA `error`; `medium` → `warning`/`warning`; `low` → `note`/`notice`. See [ADR-019](docs/decisions/ADR-019-ci-friendly-output-formats.md) for the full design.\n\nExample — upload SARIF to GitHub Code Scanning:\n\n```yaml\n- run: npx pixelcheck run --project .audit\n  env:\n    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}\n- uses: github/codeql-action/upload-sarif@v3\n  if: always()\n  with:\n    sarif_file: reports/<run-id>/audit.sarif\n```\n\n### PR diff report\n\nPosting a \"did this PR make UX better or worse?\" summary as a PR comment is two commands:\n\n```yaml\n# Audit main → audit PR → diff → post\n- run: pixelcheck run --tag main && pixelcheck run --tag pr\n- run: pixelcheck diff <MAIN_RUN_ID> <PR_RUN_ID> --format markdown --output diff.md\n- uses: marocchino/sticky-pull-request-comment@v2\n  with: { path: diff.md }\n```\n\nThe Markdown contains:\n- A headline metrics table (overall score / issues / critical issues / cost / duration) with ▲ / ▼ polarity arrows\n- Per-dimension changes (sorted by absolute delta magnitude)\n- 🆕 New issues raised by this PR (with severity tags + recommendations)\n- ✅ Resolved issues fixed by this PR\n- A \"no meaningful UX changes\" message when both lists are empty\n\nOther output formats: `--format html` for email / Slack, `--format json` for downstream charting, `--format text` (default) for terminal. Use `--output <path>` to write directly to a file (extension auto-detects format) or omit to print to stdout. See [ADR-022](docs/decisions/ADR-022-pr-diff-report.md) for the full design.\n\nNotifications: Slack webhook and Telegram bot on completion.\n\n## MCP Server\n\nPixelCheck ships an MCP server that lets any Model Context Protocol client (Claude Code, Cursor, Cline, Continue, Zed agent) drive audits without leaving its workflow.\n\n### Register with Claude Code\n\nAdd to `~/.mcp.json` (or your client's equivalent):\n\n```json\n{\n  \"mcpServers\": {\n    \"pixelcheck\": {\n      \"command\": \"pixelcheck-mcp\",\n      \"env\": {\n        \"ANTHROPIC_API_KEY\": \"sk-ant-...\"\n      }\n    }\n  }\n}\n```\n\n### Tools\n\n| Tool | Kind | Use when |\n|---|---|---|\n| `audit_url` | preset | You want the full audit pipeline against one URL — agent loop, scoring, JSON + HTML report. |\n| `explore_url` | preset | You want a quick autonomous run with a free-form goal; no scenario YAML needed. |\n| `see` | primitive | You want to look at a URL once and get back DOM summary + screenshot + console errors + an optional natural-language note. 0 LLM cost when `goal` is omitted. |\n| `act` | primitive | You want to drive an action sequence (click / fill / scroll / screenshot / natural-language `act` / vision `note`) and get back per-step status + final DOM + screenshot. |\n| `extract` | primitive | You want a typed payload back from a URL — pricing tiers, feature lists, FAQ entries — shaped exactly the way you asked for. Hand the tool a JSON Schema; get back `data` matching it plus DOM / console / screenshot. |\n| `judge` | primitive | You want a rubric-driven critique of one URL — aesthetic polish, dark-pattern risk, or any custom rubric. Returns per-criterion scores (0..10) + severity-graded findings with on-screen locations. 1 vision call. |\n| `compare` | primitive | You want an A/B comparison of two URLs against the same rubric. Default `double_blind` mode judges each side independently then synthesises a comparison (3 vision calls, free of anchoring bias). `fast` mode is 1 call (cheaper, anchored). |\n| `list_personas` | meta | Discover which personas are installed in a project. |\n| `list_scenarios` | meta | Discover which scenarios are installed in a project. |\n| `list_capabilities` | meta | Self-describe the server: every shipped tool with kind / cacheability / static cost band / side-effects / dependency declarations, plus the public env-var table and live result-cache state. Pure introspection — call it once on first connect to plan the rest of your session. |\n| `calibrate_critic` | meta | Run the critic calibration gate against labeled fixtures (returns pass/fail + agreement metrics). |\n| `get_last_report` | meta | Read the most recent audit's summary JSON from the local history DB. |\n\n#### `see` — one-shot navigation snapshot\n\nThe lightest tool in the kit. Call it when you want to ask \"what's on this page right now?\" without spinning up a full audit.\n\n```jsonc\n// MCP tools/call arguments\n{\n  \"url\": \"https://stripe.com/pricing\",\n  \"goal\": \"Is there a free tier?\",      // optional — runs one vision call, ~$0.005\n  \"wait_for\": \"networkidle\",            // or \"load\", \"domcontentloaded\", or a CSS selector\n  \"viewport_width\": 1280,\n  \"viewport_height\": 800,\n  \"include_dom\": true,\n  \"include_console\": true,\n  \"headless\": true,\n  \"timeout_ms\": 30000\n}\n```\n\nReturns a `SeeResult` (see [docs/schemas/see-result.schema.json](./docs/schemas/see-result.schema.json)) with `url_final` (post-redirect), `title`, `dom` (interactive count + headings + summary), `console.errors`, `screenshot` (path + sha256), and `note` (the goal answer when set). Artefacts land under `$AUDIT_SEES_DIR` or `~/.pixelcheck/sees/<UTC-iso>-<rand6>/`. See [ADR-011](./docs/decisions/ADR-011-see-primitive.md) for design rationale.\n\n#### `act` — execute an action sequence\n\nRun a sequence of browser actions (deterministic + AI), get back a per-step trace, the final DOM, and a final screenshot. Engine is auto-selected: pure-deterministic step lists run on raw Playwright (~1 s cold start, no LLM key needed), Stagehand only spins up when at least one step is `{ \"type\": \"act\" }`.\n\n```jsonc\n// MCP tools/call arguments\n{\n  \"url\": \"https://stripe.com/pricing\",\n  \"steps\": [\n    { \"type\": \"fill\", \"selector\": \"input[name=email]\", \"value\": \"user@example.com\" },\n    { \"type\": \"click\", \"selector\": \"button[type=submit]\" },\n    { \"type\": \"wait_for\", \"selector\": \".dashboard\", \"state\": \"visible\" },\n    { \"type\": \"screenshot\", \"label\": \"after-login\" },\n    { \"type\": \"act\", \"instruction\": \"Click the Upgrade to Pro button\" },\n    { \"type\": \"note\", \"goal\": \"Was the upgrade modal shown? Any error?\" }\n  ],\n  \"stop_on_error\": true\n}\n```\n\nEach step kind:\n\n| Kind | Cost | Notes |\n|---|---|---|\n| `goto` | 0 | Re-navigate. Supports `wait_for` (load / domcontentloaded / networkidle / CSS selector). |\n| `click` / `fill` / `press` / `wait` / `wait_for` / `scroll` | 0 | Direct Playwright. No LLM. |\n| `screenshot` | 0 | Writes `<label>.png` (default `step-<index>.png`) into the per-call artefacts dir. |\n| `act` | ~1 LLM call | Stagehand-resolved natural-language action. Forces the engine to Stagehand for the whole session. |\n| `note` | ~$0.005 | One vision call against the current page. Works on either engine. |\n\nReturns an `ActResult` (see [docs/schemas/act-result.schema.json](./docs/schemas/act-result.schema.json)) with `engine` (`\"playwright\"` | `\"stagehand\"`), `steps[]` (each with `status`, `duration_ms`, `cost_usd`, optional `screenshot` / `note` / `output` / `error`), final `dom` / `console` / `screenshot`, and total `cost_usd`. Failure semantics: `stop_on_error: true` (default) skips remaining steps after the first failure (recorded as `status: \"skipped\"`); `false` runs them all and the top-level `status` is `\"error\"` if any failed. Artefacts land under `$AUDIT_ACTS_DIR` or `~/.pixelcheck/acts/<UTC-iso>-<rand6>/`. See [ADR-012](./docs/decisions/ADR-012-act-primitive.md) for design rationale.\n\n#### `extract` — schema-bound structured extraction\n\nHand the tool a JSON Schema describing the payload you want; get back `data` matching the shape. One LLM call per invocation. Always Stagehand (extract is fundamentally LLM-driven; there is no deterministic alternative for \"give me an arbitrarily-shaped object\").\n\n```jsonc\n// MCP tools/call arguments\n{\n  \"url\": \"https://stripe.com/pricing\",\n  \"schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"plans\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"name\":     { \"type\": \"string\" },\n            \"price\":    { \"type\": \"number\", \"description\": \"Monthly price in USD\" },\n            \"features\": { \"type\": \"array\",  \"items\": { \"type\": \"string\" } }\n          },\n          \"required\": [\"name\", \"price\"]\n        }\n      }\n    },\n    \"required\": [\"plans\"]\n  },\n  \"instruction\": \"Extract every pricing plan card\",   // optional — auto-synthesised from schema field names if omitted\n  \"selector\": \"main\"                                   // optional — constrain to a sub-region\n}\n```\n\nJSON Schema subset accepted (the converter rejects everything else with a precise error message naming the keyword and JSON path):\n\n| Accepted | Rejected |\n|---|---|\n| `type: object \\| array \\| string \\| number \\| integer \\| boolean \\| null` | `oneOf`, `anyOf`, `allOf`, `not` |\n| `type: [\"string\", \"null\"]` (nullable shorthand) | `$ref`, `patternProperties`, `dependencies` |\n| `properties`, `required`, `items`, `enum`, `description`, `nullable` | `if` / `then` / `else`, `const` (use a single-element `enum` instead) |\n| `additionalProperties` (accepted, ignored — `z.object` strips by default) | |\n| `pattern`, `minLength`, `maxLength`, `minimum`, `maximum` (accepted, not enforced — the LLM does not honour them) | |\n\nThe root must be `type: \"object\"` because Stagehand's `extract()` requires an object schema. A bare `{ properties: {…} }` (no `type`) is accepted as object-shorthand.\n\nReturns an `ExtractResult` (see [docs/schemas/extract-result.schema.json](./docs/schemas/extract-result.schema.json)) with `engine: \"stagehand\"`, `data` (matching your schema), `schema_used` / `instruction_used` / `selector_used` (echoed for client-side re-validation and debugging), `dom` / `console` / `screenshot`, and `cost_usd` derived from Stagehand's `metrics.extractPromptTokens` × `estimateCost(model, …)`. The `data.json` artefact is also persisted alongside the screenshot for replay. If a tight cost-guard cap trips during `recordUsage`, `status` flips to `\"error\"` but `data` and `cost_usd` are still surfaced (partial-success). Artefacts land under `$AUDIT_EXTRACTS_DIR` or `~/.pixelcheck/extracts/<UTC-iso>-<rand6>/`. See [ADR-013](./docs/decisions/ADR-013-extract-primitive.md) for design rationale.\n\n#### `judge` — rubric-driven page critic\n\nScore one URL against a rubric — aesthetic polish, dark-pattern risk, or any custom criteria you supply. One vision call per invocation. Built-in rubrics are reified data in `src/core/critics/`; the criterion ids are part of the public contract so consumers can join verdicts back to the rubric across runs.\n\n```jsonc\n// MCP tools/call arguments\n{\n  \"url\": \"https://stripe.com/pricing\",\n  \"rubrics\": [\"aesthetic\", \"dark_pattern\"],          // 8 + 12 built-in criteria\n  \"custom_criteria\": [                                // optional one-off rubric\n    { \"id\": \"pricing_clarity\", \"label\": \"Pricing clarity\", \"description\": \"Is total cost visible without scrolling?\" }\n  ],\n  \"persona\": \"us-power-user-desktop\",                  // optional — drives viewport/locale via personas/\n  \"wait_for\": \"networkidle\"\n}\n```\n\nBuilt-in rubrics:\n\n| Rubric | Criteria | Examples |\n|---|---|---|\n| `aesthetic` (8) | `visual_hierarchy`, `typography`, `alignment_grid`, `color_contrast`, `spacing_rhythm`, `polish`, `information_density`, `brand_cohesion` | Benchmarked against Stripe / Linear / Vercel / Notion |\n| `dark_pattern` (12) | `forced_continuity`, `hidden_costs`, `preselected_options`, `fake_urgency`, `confirmshaming`, `obstruction`, `misdirection`, `trick_questions`, `disguised_ads`, `bait_and_switch`, `privacy_zuckering`, `nagging` | Brignull taxonomy + Norwegian Consumer Council 2018 |\n| `custom` | Caller-supplied | Any one-off rubric — pricing clarity, conversion path, accessibility narrative, … |\n\nScore direction is uniform: **higher = better**, regardless of kind. Aesthetic 10 = excellent; dark-pattern 10 = no dark pattern detected. So `overall_score` (mean of all verdict scores) is monotonic across mixed rubrics.\n\nReturns a `JudgeResult` (see [docs/schemas/judge-result.schema.json](./docs/schemas/judge-result.schema.json)) with `rubrics`, `criteria` (the full rubric list rendered into the prompt), `verdicts[]` (per-criterion `{ criterion_id, score, rationale, evidence }`), `findings[]` (severity-graded issues with `location`), `overall_score`, `summary`, plus the standard `dom` / `console` / `screenshot` / `cost_usd` envelope. Artefacts land under `$AUDIT_JUDGES_DIR` or `~/.pixelcheck/judges/<UTC-iso>-<rand6>/judge.json`. See [ADR-014](./docs/decisions/ADR-014-judge-and-compare-primitives.md) for design rationale.\n\n#### `compare` — A/B page comparison\n\nRun an A/B comparison of two pages against a shared rubric. Default mode is **`double_blind`**: judge each side independently (parallel) with the same rubric, then run ONE synthesis vision call that sees both screenshots side-by-side with the prior judgements as context. Three vision calls total; wall-clock ≈ two calls because the judges run in parallel. This mirrors commercial UX-review practice — Nielsen Norman, Baymard Institute — where each candidate is evaluated independently before the comparison synthesis. The reason is anchoring bias: when a model is asked to score two pages in one prompt, absolute scores get pulled toward the difference between them, not the page itself.\n\n`fast` mode collapses to a single side-by-side vision call — cheaper (~3× cheaper) but anchored. Opt in for batch comparisons (e.g. evaluating 100 competitors overnight) where the cost ratio matters more than per-call accuracy.\n\n```jsonc\n// MCP tools/call arguments\n{\n  \"a\": { \"url\": \"https://stripe.com/pricing\" },\n  \"b\": { \"url\": \"https://intercom.com/pricing\", \"viewport_width\": 375, \"viewport_height\": 812 },\n  \"rubrics\": [\"aesthetic\", \"dark_pattern\"],\n  \"mode\": \"double_blind\"                                // default; use \"fast\" for cheap batches\n}\n```\n\nPer-side `viewport` lets you compare e.g. desktop A vs mobile B. Either side may be a pre-captured snapshot from a prior `see` / `extract` / `judge` call (`{ \"capture\": { ... } }`); the tool will skip the browser for that side.\n\nReturns a `CompareResult` (see [docs/schemas/compare-result.schema.json](./docs/schemas/compare-result.schema.json)) with `mode`, `rubrics`, `criteria`, `side_a` / `side_b` (each carrying the embedded JudgeResult in double_blind mode + per-side screenshot + artefacts dir), `per_criterion[]` (`{ criterion_id, score_a, score_b, winner: \"a\"|\"b\"|\"tie\", rationale }`), `overall_winner`, `summary`, and total `cost_usd`. Artefacts land under `$AUDIT_COMPARES_DIR` or `~/.pixelcheck/compares/<UTC-iso>-<rand6>/` with `a/` and `b/` subdirs and a `compare.json` sidecar.\n\n#### `list_capabilities` — self-describe\n\nCall once on first connect to get a structured map of the whole server: every tool with its kind, input schema, result schema title, **cacheability**, **static cost-estimate band**, **side-effects**, and **dependency declarations**; plus the public env-var table and live state of the result cache.\n\n```jsonc\n// MCP tools/call arguments — none required\n{}\n```\n\nReturns a `ListCapabilitiesResult` (see [docs/schemas/list-capabilities-result.schema.json](./docs/schemas/list-capabilities-result.schema.json)):\n\n```jsonc\n{\n  \"schema_version\": \"1.2.0\",\n  \"server\": { \"name\": \"pixelcheck\", \"version\": \"0.3.0\" },\n  \"result_schema_version\": \"1.2.0\",\n  \"tools\": [\n    {\n      \"name\": \"judge\",\n      \"kind\": \"primitive\",\n      \"result_schema\": \"JudgeResult\",\n      \"cacheable\": true,\n      \"cost_estimate_usd\": { \"typical\": 0.02, \"min\": 0.01, \"max\": 0.06, \"unit\": \"per_call\", \"notes\": \"...\" },\n      \"side_effects\": [\"navigation\", \"network_egress\", \"fs_writes_artifacts\"],\n      \"requires\": { \"api_keys\": [\"ANTHROPIC_API_KEY\"], \"browser\": true }\n      /* …plus name / description / input_schema */\n    }\n    /* …11 more rows */\n  ],\n  \"env\": [\n    { \"name\": \"ANTHROPIC_API_KEY\", \"scope\": \"auth\", \"default\": \"\", \"required\": true, \"description\": \"...\" }\n    /* …20 more rows across auth / cache / cost_guard / artifacts / logging / memory / reports */\n  ],\n  \"cache\": { \"enabled\": true, \"ttl_ms_default\": 86400000, \"path\": \"~/.pixelcheck/result-cache.db\" }\n}\n```\n\n**Pure introspection.** No LLM, no browser, no probe of secret presence. Secret env vars are *named* (so you know what to set) but values are never returned. The cache file path *is* exposed because paths are not secrets — agents writing diagnostic / cleanup scripts genuinely need them. See [ADR-016](./docs/decisions/ADR-016-mcp-self-describe.md) for design rationale, including why `tools/list` keeps the strict-spec subset and why runtime secret-presence is deliberately not probed.\n\nEvery tool response carries a top-level `schema_version` field per [docs/contracts/RESULT_SCHEMA.md](./docs/contracts/RESULT_SCHEMA.md). Two parallel tool calls in one server process see independent run-USD cost caps (per [ADR-009](./docs/decisions/ADR-009-concurrency-safety.md)) but share the persistent daily ledger.\n\nAdding a new tool: drop a file under `src/mcp/tools/<name>.ts` exporting a `ToolDefinition`, then push it into `ALL_TOOLS` in `src/mcp/server.ts`. See [ADR-010](./docs/decisions/ADR-010-mcp-tool-registry.md) for the registry rationale.\n\n## Multi-Project Support\n\nOne PixelCheck install serves all your projects:\n\n```\npixelcheck/\n |-- personas/              # 18 shared personas (used by all projects)\n |-- projects/\n      |-- my-saas/          # Project A\n      |    |-- config.yaml\n      |    |-- scenarios/\n      |-- my-mobile-web/    # Project B\n      |    |-- config.yaml\n      |    |-- scenarios/\n      |    |-- personas/    # Optional: project-specific persona overrides\n      |-- my-docs-site/     # Project C\n           |-- config.yaml\n           |-- scenarios/\n```\n\n## Safety\n\n- **Stripe live key protection** — refuses to start if `pk_live_` detected in environment\n- **Credential redaction** — OAuth tokens, passwords, API keys, and webhook URLs are never written to reports OR to logs (two layers: well-known field names like `apiKey` / `password` / `token` / `cookie` are always censored, and concrete env-derived secret values are substring-replaced anywhere they appear, including inside log messages)\n- **Computer Use guardrails** — Anthropic's prompt-injection classifier enabled by default\n- **Budget cap** — stops spawning new audit units when cumulative API cost exceeds your threshold\n\n## Logging\n\nInternal events use a structured logger (pino). Output goes to **stderr**, so stdout stays clean for CLI results and the MCP stdio protocol. By default the format is human-readable when stderr is a TTY and JSON otherwise.\n\n| Env var | Values | Default | Effect |\n|---|---|---|---|\n| `LOG_LEVEL` | `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `silent` | `info` | Minimum log level |\n| `LOG_PRETTY` | `1`, `true`, `0`, `false`, `auto` | `auto` | Force pretty-print or JSON; `auto` decides by TTY |\n| `LOG_FILE` | `/path/to.log` | unset | Additionally tee logs to a file |\n\nExamples:\n\n```sh\n# CI / piped: JSON to stderr automatically (no TTY)\npixelcheck run --project projects/my-app 2> audit.log\n\n# Force JSON even in a terminal\nLOG_PRETTY=0 pixelcheck run --project projects/my-app\n\n# Verbose debugging\nLOG_LEVEL=debug pixelcheck run --project projects/my-app\n```\n\n## Cost Guard\n\nA process-wide spend cap protects against runaway LLM bills. Every Anthropic API call is tracked against two limits:\n\n- **Per-run** — single audit / MCP tool invocation. Reset at run start.\n- **Per-day** — UTC-day total persisted across processes in a JSON ledger (default `~/.pixelcheck/cost-ledger.json`, override via `AUDIT_COST_LEDGER_PATH`).\n\nExceeding any cap throws `BudgetExceededError` so the calling loop stops immediately. The ledger auto-prunes entries older than 30 days.\n\n| Env var | Default | Effect |\n|---|---|---|\n| `AUDIT_COST_MAX_RUN_USD` | `5` | Max USD per audit run / MCP tool call |\n| `AUDIT_COST_MAX_RUN_TOKENS` | `10000000` | Max input+output tokens per run |\n| `AUDIT_COST_MAX_DAILY_USD` | `50` | Max USD per UTC day across all runs |\n| `AUDIT_COST_MAX_DAILY_TOKENS` | `100000000` | Max input+output tokens per UTC day |\n| `AUDIT_COST_LEDGER_PATH` | `~/.pixelcheck/cost-ledger.json` | Path to the persistent daily ledger |\n| `AUDIT_COST_GUARD_DISABLED` | unset | `1` / `true` to bypass entirely (CI / tests) |\n\nThe cost guard layers over (and is independent of) the runner's `budget_usd` cap, which only stops the runner from scheduling new units. The cost guard catches direct MCP tool calls, computer-use loops, and instruction mutations that the unit scheduler doesn't see.\n\nInspect the current state via the snapshot included in the `run started` log line, or:\n\n```sh\nLOG_LEVEL=debug pixelcheck run --project projects/my-app\n# emits one \"llm usage recorded\" debug line per Anthropic call with running totals\n```\n\n## Concurrency Safety\n\nPixelCheck is safe to run from multiple processes at once — two parallel `pixelcheck` terminals, an MCP server fielding two `audit_url` calls in parallel, or a CLI run alongside an MCP-served call. Specifically:\n\n- **Cost ledger** (`cost-ledger.json`): protected by a cross-process advisory lockfile (`<ledger>.lock`). Concurrent recorders never lose updates.\n- **Per-run cost counters**: each MCP tool dispatch and each `runAudit` call gets its own `AsyncLocalStorage` scope, so two parallel calls have independent run-USD caps. The persistent daily ledger is still shared.\n- **Memory DB** (`memory.db`): `record(fact)` uses one atomic `INSERT … ON CONFLICT DO UPDATE`. No SELECT-then-write race.\n- **Visual diff baselines**: first-run bootstrap copies to a `.tmp` path then `linkSync`s into place. Two parallel first-runs both succeed; the first writer wins.\n\nIf a process crashes while holding the cost-ledger lock, the lock auto-recovers after 30 seconds (or sooner if the holder pid is no longer alive). See [ADR-009](docs/decisions/ADR-009-concurrency-safety.md) for design.\n\n### SQLite stores share a unified migration runner\n\nPixelCheck uses four local SQLite files (`history.db` / `memory.db` / `plan-cache.db` / `result-cache.db`). They all open through `src/core/db-migrate.ts > openManagedDatabase()`, which handles the parent-directory creation, `busy_timeout` pragma, file-locked WAL transition, and a `PRAGMA user_version`-driven migration walk in one place. Each migration runs in its own `BEGIN IMMEDIATE` / `COMMIT` block so a SQL failure rolls every CREATE / ALTER / INSERT in that step back atomically — partial schema is impossible. Older binaries opening newer DBs fail loudly with `MigrationVersionError` instead of running broken queries against missing columns. See [ADR-026](docs/decisions/ADR-026-unified-db-migrations.md) for design.\n\n## Result Cache\n\nA persistent local cache memoises results from the deterministic primitives so repeated identical calls return instantly with `cost_usd = 0`. AI agents can plan more aggressively without burning fresh vision tokens on every tool call.\n\n**Cached primitives:**\n\n| Primitive | Cached | Notes |\n|---|---|---|\n| `judge`   | ✅ | Same URL + rubrics + custom criteria + persona/model → same verdict. |\n| `extract` | ✅ | Same URL + schema + instruction + selector + persona/model → same `data`. |\n| `see`     | ✅ when `goal` is set | Without a goal there is no LLM cost — caching a snapshot would risk staleness. |\n| `act`     | ❌ | State-changing semantics; always runs fresh. |\n| `compare` | Transparent | Its two per-side `judge` calls hit cache automatically; the synthesis call is not separately cached. |\n\n**Hit/miss semantics:** every cache-aware result carries an optional `cache?: { hit, age_ms, key, cost_saved_usd? }` field. On hit the result's own `cost_usd` is **zeroed** and the original cost moves to `cache.cost_saved_usd` — so callers summing nested costs (e.g. `compare`) do not double-count cached work.\n\n**Configuration:**\n\n| Env var | Default | Effect |\n|---|---|---|\n| `AUDIT_RESULT_CACHE_PATH` | `~/.pixelcheck/result-cache.db` | SQLite path; isolate per environment |\n| `AUDIT_RESULT_CACHE_TTL_MS` | `86400000` (24h) | Entries older than this are misses + pruned |\n| `AUDIT_RESULT_CACHE_DISABLED` | unset | `1` / `true` to bypass entirely (read = miss, write = no-op) |\n| `AUDIT_RESULT_CACHE_MAX_ROWS` | `10000` | LRU cap; oldest `last_used_at` rows evicted past this. `0` disables. |\n| `AUDIT_RESULT_CACHE_MAX_DISK_MB` | `500` | LRU cap by DB size; same eviction order. `0` disables. |\n\n**Per-call overrides** (also exposed on each MCP tool as `cache` / `cache_bust` / `cache_ttl_ms`):\n\n- `cache: false` — skip read and write for this one call.\n- `cacheBust: true` — skip read but persist the new result so subsequent identical calls hit cache.\n- `cacheTtlMs: number` — override the TTL for this call.\n\n**Schema-version invalidation:** entries written under a different `RESULT_SCHEMA_VERSION` are treated as misses and removed at the next prune. The cache survives additive minor bumps automatically; major bumps invalidate everything.\n\nSee [ADR-015](docs/decisions/ADR-015-result-cache.md) for design.\n\n## Artifact retention\n\nEach MCP primitive call (`see` / `act` / `extract` / `judge` / `compare`) writes a per-call subdirectory under `~/.pixelcheck/<kind>/` containing screenshots, DOM dumps, payload JSON, and the LLM response. Long-running MCP servers can accumulate gigabytes over a month. PixelCheck enforces a 30-day retention window by default and prunes lazily.\n\n```bash\npixelcheck prune          # explicit cleanup; prints summary, exit 1 on errors\n```\n\nThe MCP server runs the same prune at most once per 24 hours on startup\n(`prune-stamp.json` records the last run; subsequent connects within the\nwindow skip prune entirely).\n\n| Env var | Default | Effect |\n|---|---|---|\n| `AUDIT_SEES_RETENTION_DAYS` | 30 | Retention window for `see` artifacts; `0` disables |\n| `AUDIT_ACTS_RETENTION_DAYS` | 30 | Same, for `act` |\n| `AUDIT_EXTRACTS_RETENTION_DAYS` | 30 | Same, for `extract` |\n| `AUDIT_JUDGES_RETENTION_DAYS` | 30 | Same, for `judge` |\n| `AUDIT_COMPARES_RETENTION_DAYS` | 30 | Same, for `compare` |\n| `AUDIT_<KIND>_DIR` | `~/.pixelcheck/<kind>` | Custom storage dir per kind |\n\nSetting a retention to `0` means **infinite retention** (skip prune for that kind), matching how every Linux retention tool behaves. To bulk-delete a kind, use `rm -rf ~/.pixelcheck/<kind>` directly.\n\n## Built With\n\n- [Playwright](https://playwright.dev/) — browser automation\n- [Stagehand 3.x](https://github.com/browserbase/stagehand) — AI-driven semantic browser control\n- [Claude](https://anthropic.com/claude) (Vision + Computer Use) — visual evaluation and pixel-level review\n- [axe-core](https://github.com/dequelabs/axe-core) — WCAG accessibility auditing\n- [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) — local audit history and trend tracking\n\n## How Is This Different?\n\nYou have four real options if you want an AI agent to operate the visual web today, and each makes a different bet:\n\n- **OSS automation frameworks** — browser-use (91k★), Stagehand (22k★), Skyvern (21k★). Best-in-class at *executing tasks* an agent dictates. None ship a multi-persona simulation layer, none have a strict result-schema contract designed for cacheable AI workflows.\n- **Rule-based auditors** — axe-core (7k★), pa11y (4.4k★), Lighthouse. Excellent at \"does this pass WCAG?\" Silent on \"is this product actually good?\"\n- **Hosted agentic browsers** — Comet, Atlas, BrowserOS, Dia. Consumer products that replace Chrome. You give them a credit card and a session. They give you UI, not infrastructure.\n- **PixelCheck** — the MCP server beneath your AI agent's workflow. Fully local, fully OSS, fully owned.\n\n| | OSS Frameworks | Rule-Based Auditors | Hosted Agentic Browsers | **PixelCheck** |\n|---|---|---|---|---|\n| **Question answered** | How do I control a browser? | Does this pass WCAG 2.x? | Can a product look at the web for me? | How does *my AI agent* see and operate the web? |\n| **Primary interface** | Library / SDK | CLI | Desktop app + cloud session | **MCP server** (+ CLI for humans) |\n| **Intelligence** | LLM-driven actions | Static rules | Hosted LLM (you pay per session) | LLM vision + rules + Computer Use, your LLM key |\n| **User simulation** | Single anonymous session | None | Single signed-in session | 18 personas × 17 countries × 6 script systems |\n| **Anti-detection** | None | N/A | Built-in (browser identity) | 9 fingerprints + 15 stealth patches |\n| **Output contract** | Action results | Pass/fail checklist | Conversational replies | **31 published JSON Schemas + 89 named API** |\n| **History** | None | None | Per-session, vendor-locked | SQLite trends + run-to-run diff, yours |\n| **Cost model** | Free OSS, your LLM bill | Free OSS | Subscription + per-session | Free OSS, your LLM bill, no PixelCheck markup |\n| **Where your data lives** | Your machine | Your machine | Vendor cloud | **Your machine. Period.** |\n| **Lock-in** | Sometimes (cloud add-ons) | None | Maximum | None — MIT, no paid tier, no commercial fork |\n\nNo existing open-source project combines MCP-first browser primitives, multi-persona simulation, AI vision scoring, WCAG analysis, stealth fingerprints, and historical trend tracking. **PixelCheck is the missing infrastructure layer between AI agents and the visual web** — and it's the only one in the table above where the answer to \"what happens to my data\" is \"it never leaves your machine.\"\n\n## Test Coverage\n\nRun with measurement:\n\n```bash\nnpm run test:coverage          # writes ./coverage/index.html\nnpm run test:coverage:check    # CI gate — fails on regression below thresholds\n```\n\nCoverage is enforced via `vitest.config.ts > coverage.thresholds` (provider `v8`). Entry-points (`cli.ts`, `index.ts`, `mcp/server.ts`) and pure-type contracts (`core/types.ts`, `core/result-schema.ts`) are excluded — they are tested through consumers (CLI smoke + MCP `tools/list` handshake + schema round-trip tests). Counting them would dilute the signal.\n\nThe threshold floor sits at or below the current global baseline so the gate catches regression but doesn't block the build. Each new test PR ratchets the floor up after pushing it. Per-module coverage is visible in the text-table report or `coverage/index.html`. See [docs/decisions/ADR-017-coverage-tooling-and-m1-2-phase-1.md](docs/decisions/ADR-017-coverage-tooling-and-m1-2-phase-1.md) for the phase plan.\n\n## Performance regression gate\n\nHot-path benchmarks live in `tests/perf.bench.ts` and run separately from the test suite (vitest's `*.bench.ts` discovery is independent from `*.test.ts`, so `npm test` stays fast). 9 benchmarks cover the report rendering + aggregation paths most likely to regress when someone refactors a template or adds an O(N²) loop:\n\n- `renderPdfHtml` / `renderTrendsHtml` / `renderDiffMarkdown` / `renderDiffHtml`\n- `renderJunitXml` / `renderSarif`\n- `summarizeWcag` / `computeSummary` / `t() i18n lookup`\n\n```bash\nnpm run bench          # measure (writes docs/perf-current.json)\nnpm run bench:check    # compare to docs/perf-baseline.json — exit 1 on regression > 50%\nnpm run bench:update   # bake current as new baseline (after intentional perf changes)\n```\n\nThe default 50% tolerance is calibrated against measured run-to-run variance (8–53% on quiet hardware). Stricter local checks via `--tolerance 0.30`. Initial baseline was recorded as **min-of-5 consecutive runs** so regressions register as \"slower than we've ever been\" — robust to noise above the floor. See [ADR-025](docs/decisions/ADR-025-performance-regression-suite.md) for the full design.\n\n## Stability Commitment\n\nStarting **v1.0.0**, the following surfaces are stable per\n[Semantic Versioning](https://semver.org/):\n\n- **CLI** — flags, subcommands, exit codes, env var names\n- **Config schema** — `config.yaml` / `personas/*.yaml` / `scenarios/*.yaml`\n- **Result Schema** — version 1.2.0, the 31 published JSON Schemas in `docs/schemas/`\n- **MCP tool surface** — 13 tool names + input/output schemas\n- **Library exports** — 89 named exports from `src/index.ts`\n\nBreaking changes only land in **major version bumps** (v2.0, v3.0, ...). Minor\nand patch releases are guaranteed backward-compatible. Deprecation cycle is\ndocumented in [docs/DEPRECATION-POLICY.md](docs/DEPRECATION-POLICY.md):\nfeatures deprecated in v1.x continue to work for **at least two minor\nreleases** before being removed in the next major.\n\nUpgrading from v0.3 to v1.0? See [MIGRATION.md](MIGRATION.md).\n\n### Performance baseline (provisional, v1.0-rc1 calibration pending)\n\nA typical 5-unit audit (1 scenario × 5 personas, full AI pipeline) is\nexpected to land in:\n\n| Metric | v1.0 target | Notes |\n|---|---|---|\n| Wall-clock time | ~2–5 minutes | Varies by site complexity, persona count, model. v1.0-rc1 calibration will set a hard SLA. |\n| API cost | ~$0.10–$0.30 | Claude Sonnet 4.6 vision; Computer Use spikes can push to $0.50+ |\n| Memory peak | < 1 GB RSS | Chromium ~500 MB + Node heap ~300 MB |\n\n**Render hot-paths** (already tracked via `npm run bench:check` regression gate):\n\n| Path | ops/sec on M-series | Notes |\n|---|---|---|\n| `renderPdfHtml` (20-unit audit) | ~12,000 | A4 portrait + WCAG section + 5 charts |\n| `renderTrendsHtml` (100-row history) | ~1,000 | 5 inline-SVG charts |\n| `renderDiffMarkdown` (typical PR) | ~90,000 | Sticky PR comment friendly |\n| `renderSarif` (20-unit, 12 issues) | ~190,000 | Per-WCAG-SC ruleIds |\n\nThese are micro-benchmarks (single function call). Full audit pipeline\n(launch chromium → navigate → score) wall-clock baseline is being\ncalibrated in v1.0-rc1.\n\n## Contributing\n\nContributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for the\nfull developer guide (dev setup, commit conventions, PR process, ADR\npractice, branch protection).\n\nWe adopt the [Contributor Covenant 2.1](CODE_OF_CONDUCT.md) as our\ncommunity Code of Conduct.\n\nAreas where help is especially appreciated:\n- New personas for underrepresented regions/demographics\n- Scenario templates for common app patterns (e-commerce checkout, onboarding, dashboards)\n- Report format improvements\n- Cost optimization strategies\n\nFor installation troubleshooting (corporate proxy, Alpine, air-gapped, etc),\nsee [docs/INSTALLATION.md](docs/INSTALLATION.md).\n\n## Privacy & Data Handling\n\n`pixelcheck` runs entirely on your machine. The only outbound\nnetwork destination is `api.anthropic.com` for the audit calls you\nexplicitly trigger. **Zero telemetry.**\n\nWhat leaves your machine when you run an audit:\n\n- Page screenshots + DOM summaries → Anthropic Claude API\n- Your scenario step text + persona profile fields → Claude API\n- Nothing else (URLs / env vars / paths / past audits stay local)\n\nPrivacy-first defaults:\n\n- **Password / secret / API-key inputs are redacted** to `********` before\n  screenshots (`--redact-inputs`, on by default; opt out with\n  `--no-redact-inputs` only for fixture audits)\n- **First-run consent prompt** explicitly informs you what data goes to\n  Anthropic. Persisted in `~/.pixelcheck/consent.json` so subsequent\n  runs don't re-prompt. Bypass for CI / non-TTY:\n  `AUDIT_AUTO_CONSENT=1` env or `--auto-consent` flag (read [PRIVACY.md](PRIVACY.md) first).\n- **Per-run reports stored at mode 0700** (owner-only) under\n  `<projectDir>/reports/`\n\nFor full data-flow disclosure, GDPR / CCPA position, retention controls,\nand how to delete data — see [PRIVACY.md](PRIVACY.md).\n\n## Security\n\nFound a vulnerability? Please use GitHub Security Advisories (private\ndisclosure) — see [SECURITY.md](SECURITY.md). Do **not** file public\nissues for security reports.\n\n## License\n\nMIT — see [LICENSE](LICENSE) for full text.\n\nThird-party dependencies and their licenses are documented in\n[docs/THIRD_PARTY_LICENSES.md](docs/THIRD_PARTY_LICENSES.md).\n\n## Help & Reference\n\n- [FAQ.md](FAQ.md) — common questions on API key + cost, scenarios + personas, reports + output, privacy, native binaries\n- [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) — runtime errors and fixes (API + auth, audit run, browser, reports, CI, performance)\n- [docs/INSTALLATION.md](docs/INSTALLATION.md) — install matrix + corporate proxy + Alpine / Docker / air-gapped recipes\n- **API reference** — generate locally with `npm run docs:api` → `docs/api/index.html` (TypeDoc, not committed)\n- [docs/decisions/](docs/decisions/) — 28 Architecture Decision Records explaining design rationale\n\n---\n\n<p align=\"center\">\n  <strong>E2E tests verify your code works. PixelCheck gives AI agents real eyes and hands to verify your product works.</strong>\n  <br/>\n  <a href=\"#quick-start\">Get started in 2 minutes</a>\n</p>\n","readmeFilename":"README.md"}