{"_id":"@agent-e2e/harness","_rev":"11-1be0192b621dff2adda08d1de6e272bd","name":"@agent-e2e/harness","dist-tags":{"latest":"3.0.3"},"versions":{"1.0.0":{"name":"@agent-e2e/harness","version":"1.0.0","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@1.0.0","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e-harness":"dist/cli/index.js"},"dist":{"shasum":"3d284948c920b6f7becea8a17f1c829e429f5af8","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-1.0.0.tgz","fileCount":51,"integrity":"sha512-6i1l3pwNWoAj1amIn9AQts+Rur2q7XhHIu7iSV9q3dRBI80/NLJd74f4zd+z2i35wbLLYGy6I9et8un+COBulA==","signatures":[{"sig":"MEUCIQDJVyp5SKGX8vfiWD53ivmsHLkFaKVpPsf5n3HmeUuYXwIgLT4wY6cx0bwYBxtyD507QaqkCiSwWhepCyLDiPvLQPU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":293355},"type":"module","engines":{"bun":">=1.3.0","node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"}},"gitHead":"11ca5c5d53a4a2f3ec526a550101c1b0a407b361","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.7","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"zod":"^4.2.1","playwright":"^1.59.1","@modelcontextprotocol/sdk":"^1.29.0"},"peerDependenciesMeta":{"zod":{"optional":true},"playwright":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_1.0.0_1778749218758_0.16300732635635828","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@agent-e2e/harness","version":"1.0.1","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@1.0.1","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e":"dist/cli/index.js"},"dist":{"shasum":"e9b997d356398067802a9297108fa3b6a478a879","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-1.0.1.tgz","fileCount":67,"integrity":"sha512-ny3Q6xxM2GlTsjichzC323V9W0n3wnpDiCuGP+p7+naM1Quv8YRAxzIeoV51ezcNj58G5YuNjIqSg38dBrn5zg==","signatures":[{"sig":"MEQCIHiUREn0+gBj0hR3jidM6qz2Z4cBGFm0Ui4B6Ezuho5/AiA9EQE5nsJCN4FCW5Ev9YMCfKKQYMpjL5jeJAquuMt/jw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":362744},"type":"module","engines":{"bun":">=1.3.0","node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"}},"gitHead":"5f4202376148be7a6fcfa8dda58a0c66fb586fc2","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.7","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"zod":"^4.2.1","playwright":"^1.59.1","@modelcontextprotocol/sdk":"^1.29.0"},"peerDependenciesMeta":{"zod":{"optional":true},"playwright":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_1.0.1_1778760858882_0.005561085483332118","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@agent-e2e/harness","version":"1.1.0","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@1.1.0","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e":"dist/cli/index.js"},"dist":{"shasum":"0d74b94801ef25b8cb0e7f336cce86ceb4eb6f9c","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-1.1.0.tgz","fileCount":67,"integrity":"sha512-BQKKwYspykCrSDcUHnG6O4qwoy0GHchKMfkP+A6VKVQJwE88cNGIcdCj1SCWrtbAo9AUsqQ0IYF606VaACxxfw==","signatures":[{"sig":"MEQCIEYEAcJwuNggJHoNQNn/2FMmJs0ckBVQlE02xGykPpeiAiB/iXH682Rev1TvlT/b7SiLYFxfTa+O22kOFCupZ9R82g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":393400},"type":"module","engines":{"bun":">=1.3.0","node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"}},"gitHead":"221f7fdd632065e02942cfd0c114afce2591c12d","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.7","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"zod":"^4.2.1","playwright":"^1.59.1","@modelcontextprotocol/sdk":"^1.29.0"},"peerDependenciesMeta":{"zod":{"optional":true},"playwright":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_1.1.0_1778779278579_0.26871902335733555","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@agent-e2e/harness","version":"1.2.0","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@1.2.0","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e":"dist/cli/index.js"},"dist":{"shasum":"eb53ce6bc055271582182d6db7dee5c13bdfb92c","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-1.2.0.tgz","fileCount":87,"integrity":"sha512-VcRUccj4WUwTYn3q0VO1qEKyWIVvm3AwglE9G4M3mGeKAD2+5ZXj4ClobzAkTHRfufOmcpKa7xZiWbFRsIPxHg==","signatures":[{"sig":"MEUCIQCI1LjjfK+zHtlhoPjyJu1nNrYX4h6/YE6s2Vm8anWhygIgYEKQ9YK8Gq5jLdO4daQzQ791KXkVeC8/CesVFr/YueY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":483959},"type":"module","engines":{"bun":">=1.3.0","node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"}},"gitHead":"68132b7908635f5a51afb3b44eaf717b2c7eb519","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.7","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"zod":"^4.2.1","playwright":"^1.59.1","@modelcontextprotocol/sdk":"^1.29.0"},"peerDependenciesMeta":{"zod":{"optional":true},"playwright":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_1.2.0_1778837570456_0.8903241981042322","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@agent-e2e/harness","version":"1.3.0","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@1.3.0","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e":"dist/cli/index.js"},"dist":{"shasum":"867faa68388d24ebe85b7d1a67856fec12da7eef","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-1.3.0.tgz","fileCount":99,"integrity":"sha512-Dz8QrDbiP7sLsNJ6wGJkMVzWOypQ8byDwOEutUBq4ul/b8QvANI2Tr5PnSNl6jU8Wb+GPAupvh6WiuGD12gUgA==","signatures":[{"sig":"MEUCIQCDxy2unXHUEe7jkpWaGv0U5V4FZUzj1PDOagw7kmIcXAIgB2mKxQxA8exiERlTUYmaL3KHb/xlrZCU9IKCFRBj3Qw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":548894},"type":"module","engines":{"bun":">=1.3.0","node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"}},"gitHead":"afa218afb602037d0d910dba5ddaab9b0a851d3b","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.7","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"zod":"^4.2.1","playwright":"^1.59.1","@modelcontextprotocol/sdk":"^1.29.0"},"peerDependenciesMeta":{"zod":{"optional":true},"playwright":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_1.3.0_1778951056301_0.21509935901176358","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@agent-e2e/harness","version":"1.4.0","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@1.4.0","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e":"dist/cli/index.js"},"dist":{"shasum":"61ce4e26ec1d2d44b22c5f33dddb7eec1ac036a6","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-1.4.0.tgz","fileCount":111,"integrity":"sha512-6J/elfiEIKig3Aic+fqLzF6U6IwrbQkxFEf/2Y5czYl1/ROG2c7hcNCEhTou/rpj86EjzXILh288A/mVU/HlrQ==","signatures":[{"sig":"MEUCIQDQHD/NHK33YxfwGnGSFSXnfBckxYKhLZEbkFs/Mua5XAIgJ3LnKVD+1YbD+qNy+9DfowYql8fL2QIkx9MQrhhQALg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":736332},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./runtime":{"types":"./dist/runtime/index.d.ts","default":"./dist/runtime/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"},"./testcontainers":{"types":"./dist/testcontainers/index.d.ts","default":"./dist/testcontainers/index.js"}},"gitHead":"167cdec9b7f4fc038f78b9f1b99c0609997dd38c","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.8","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"jiti":"^2.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"pg":">=8","zod":"^4.2.1","playwright":"^1.59.1","testcontainers":">=11.14.0","@modelcontextprotocol/sdk":"^1.29.0","@testcontainers/postgresql":">=11.14.0"},"peerDependenciesMeta":{"pg":{"optional":true},"zod":{"optional":true},"playwright":{"optional":true},"testcontainers":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true},"@testcontainers/postgresql":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_1.4.0_1780182005436_0.30481493702980345","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@agent-e2e/harness","version":"2.0.0","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@2.0.0","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e":"dist/cli/index.js"},"dist":{"shasum":"dc42bec5d779296a7e274a76e12aecaa7bc2f7e1","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-2.0.0.tgz","fileCount":111,"integrity":"sha512-hTkfEfENfZ1lPzlPM9UI392H7DDBwXoAbHKbdIfJF0eRb1dR07yC3a6sr3M4fsIcMY5ssOa9r0vv4nox2m3xpQ==","signatures":[{"sig":"MEQCICiznxi2aXPLCB1+7lnrLVeVeDoqf76WsvPjFkfwMxx0AiAukzORvh8f89QM907se5ZYhaiHYTPowyqUlHNwUX59Gw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":740218},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./runtime":{"types":"./dist/runtime/index.d.ts","default":"./dist/runtime/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"},"./testcontainers":{"types":"./dist/testcontainers/index.d.ts","default":"./dist/testcontainers/index.js"}},"gitHead":"020b1641e3446abac840b7e846ae7993c94e1634","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.8","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"jiti":"^2.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"pg":">=8","zod":"^4.2.1","playwright":"^1.59.1","testcontainers":">=11.14.0","@modelcontextprotocol/sdk":"^1.29.0","@testcontainers/postgresql":">=11.14.0"},"peerDependenciesMeta":{"pg":{"optional":true},"zod":{"optional":true},"playwright":{"optional":true},"testcontainers":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true},"@testcontainers/postgresql":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_2.0.0_1780233742327_0.21572939137354386","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"@agent-e2e/harness","version":"3.0.0","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@3.0.0","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e":"dist/cli/index.js"},"dist":{"shasum":"4a8829a885b5490768214e17c9d28caf6be9fc73","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-3.0.0.tgz","fileCount":119,"integrity":"sha512-p9qrdgCn1hHlwrtVzdlyRDz3Mz0peoq+rN7pp2NwcVWRWXuB1A0LDoC2AKvuKqPP211m0kbVhRk7QSjxfQWbbw==","signatures":[{"sig":"MEQCIE3evdqk0yvT2iDkzCEspHdFzLSL1NTNFMC0C+QuAUWKAiAIIYZymIOrIneQHIBkt2h47XiupKbhRfMRuEFtyWentA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":772790},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./runtime":{"types":"./dist/runtime/index.d.ts","default":"./dist/runtime/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"},"./testcontainers":{"types":"./dist/testcontainers/index.d.ts","default":"./dist/testcontainers/index.js"}},"gitHead":"aa4bf9204a8794520ef23e837d40bf409defff87","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.8","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"jiti":"^2.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"pg":">=8","zod":"^4.2.1","playwright":"^1.59.1","testcontainers":">=11.14.0","@modelcontextprotocol/sdk":"^1.29.0","@testcontainers/postgresql":">=11.14.0"},"peerDependenciesMeta":{"pg":{"optional":true},"zod":{"optional":true},"playwright":{"optional":true},"testcontainers":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true},"@testcontainers/postgresql":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_3.0.0_1780308754522_0.4804508691087208","host":"s3://npm-registry-packages-npm-production"}},"3.0.1":{"name":"@agent-e2e/harness","version":"3.0.1","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@3.0.1","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e":"dist/cli/index.js"},"dist":{"shasum":"ef1543a86857aecf64b3865eb19be9b8e2a06ced","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-3.0.1.tgz","fileCount":119,"integrity":"sha512-JmxesvSI/Nh3FOF4ln4YI8gf1ZU9Y0WW5i2UFdYTzG6M3jhTT1S4N0iKrpQ2P+6Gpakej8aRTsjiEh63wxmYcw==","signatures":[{"sig":"MEUCIFfZvCgMGjDVqjM4HkyujL5aduwVJoIJaUdyDfWyf7eZAiEAmnFL8+0uics5I+Zsp4wkTxiKRlkCROXgG7DuAPEoCIY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":772819},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./runtime":{"types":"./dist/runtime/index.d.ts","default":"./dist/runtime/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"},"./testcontainers":{"types":"./dist/testcontainers/index.d.ts","default":"./dist/testcontainers/index.js"}},"gitHead":"38b3e6607cc1b1ed93b58d4ca9b0c253578871a0","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.8","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"jiti":"^2.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"pg":">=8","zod":"^4.2.1","playwright":"^1.59.1","testcontainers":">=11.14.0","@modelcontextprotocol/sdk":"^1.29.0","@testcontainers/postgresql":">=11.14.0"},"peerDependenciesMeta":{"pg":{"optional":true},"zod":{"optional":true},"playwright":{"optional":true},"testcontainers":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true},"@testcontainers/postgresql":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_3.0.1_1780309747503_0.2913839771208837","host":"s3://npm-registry-packages-npm-production"}},"3.0.2":{"name":"@agent-e2e/harness","version":"3.0.2","keywords":["agent","e2e","mcp","playwright","testing","automation"],"author":{"name":"Aitor Roses"},"license":"MIT","_id":"@agent-e2e/harness@3.0.2","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"bin":{"agent-e2e":"dist/cli/index.js"},"dist":{"shasum":"95724c1d7e46ec22ea94266e196076069f7dabb2","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-3.0.2.tgz","fileCount":119,"integrity":"sha512-zMgRGa+jtlZgvREudu+BW/uvBSdLWjb/Ec40Hje1WBSc+pM0wkSo1ijFGMH96H5Zwk6stwwkeqQT5ggjkZEh0g==","signatures":[{"sig":"MEUCIQC+IS3axUUQQNovT7nJ84zZhir3LlpEC7rCe8dZOO3tcgIgbYrREIdE/QsXK5GwvrdxQL7iRal6Om7BlG5Qedcb4GE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":772837},"type":"module","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./runtime":{"types":"./dist/runtime/index.d.ts","default":"./dist/runtime/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"},"./testcontainers":{"types":"./dist/testcontainers/index.d.ts","default":"./dist/testcontainers/index.js"}},"gitHead":"e1d24a7a6c91613a0e896212de2de6d6f9acd01f","scripts":{"test":"npm run build && vitest run","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"repository":{"url":"git+https://github.com/aitoroses/agent-e2e-harness.git","type":"git","directory":"packages/harness"},"_npmVersion":"10.9.8","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"jiti":"^2.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"pg":">=8","zod":"^4.2.1","playwright":"^1.59.1","testcontainers":">=11.14.0","@modelcontextprotocol/sdk":"^1.29.0","@testcontainers/postgresql":">=11.14.0"},"peerDependenciesMeta":{"pg":{"optional":true},"zod":{"optional":true},"playwright":{"optional":true},"testcontainers":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true},"@testcontainers/postgresql":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/harness_3.0.2_1780310370748_0.8609181616970889","host":"s3://npm-registry-packages-npm-production"}},"3.0.3":{"name":"@agent-e2e/harness","version":"3.0.3","type":"module","description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","keywords":["agent","e2e","mcp","playwright","testing","automation"],"repository":{"type":"git","url":"git+https://github.com/aitoroses/agent-e2e-harness.git","directory":"packages/harness"},"bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","author":{"name":"Aitor Roses"},"license":"MIT","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./stack":{"types":"./dist/stack/index.d.ts","default":"./dist/stack/index.js"},"./runtime":{"types":"./dist/runtime/index.d.ts","default":"./dist/runtime/index.js"},"./dev-mcp":{"types":"./dist/dev-mcp/index.d.ts","default":"./dist/dev-mcp/index.js"},"./verify":{"types":"./dist/verify/index.d.ts","default":"./dist/verify/index.js"},"./playwright-mcp":{"types":"./dist/playwright-mcp/index.d.ts","default":"./dist/playwright-mcp/index.js"},"./artifacts":{"types":"./dist/artifacts/index.d.ts","default":"./dist/artifacts/index.js"},"./testcontainers":{"types":"./dist/testcontainers/index.d.ts","default":"./dist/testcontainers/index.js"}},"scripts":{"clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","build":"npm run clean && tsc -p tsconfig.json && chmod +x dist/cli/index.js","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit","test":"npm run build && vitest run"},"peerDependencies":{"@modelcontextprotocol/sdk":"^1.29.0","@testcontainers/postgresql":">=11.14.0","pg":">=8","playwright":"^1.59.1","testcontainers":">=11.14.0","zod":"^4.2.1"},"bin":{"agent-e2e":"dist/cli/index.js"},"peerDependenciesMeta":{"playwright":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true},"zod":{"optional":true},"@testcontainers/postgresql":{"optional":true},"pg":{"optional":true},"testcontainers":{"optional":true}},"publishConfig":{"access":"public"},"dependencies":{"jiti":"^2.7.0"},"_id":"@agent-e2e/harness@3.0.3","gitHead":"6bb9f145fcf97cdc4b9b7872da1bdc728b1b1a04","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-grIw9lDMBJvAuapU7sl1HBKQZExytLuldPuoOCkDl11ftDiUk474BneIYx8uX9vtZS8Ynfc3SiXLfIA1ArH1Xg==","shasum":"d0b5d754695f2fc4b9ee68fd84aeaaec18fbe0c4","tarball":"https://registry.npmjs.org/@agent-e2e/harness/-/harness-3.0.3.tgz","fileCount":119,"unpackedSize":777240,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD+SDQVS/CwvDFkpPj+jsk0YL18U3kl6BtXMZLIeBjHUAIgY7IUEbpIkIGaSeeEGlDkFLbN4eIKmWXBCLf501Qern8="}]},"_npmUser":{"name":"grayfox","email":"aitor.oses@gmail.com"},"directories":{},"maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/harness_3.0.3_1780311334490_0.20156859017054551"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-14T09:00:18.676Z","modified":"2026-06-01T10:55:34.819Z","1.0.0":"2026-05-14T09:00:18.922Z","1.0.1":"2026-05-14T12:14:19.080Z","1.1.0":"2026-05-14T17:21:18.731Z","1.2.0":"2026-05-15T09:32:50.619Z","1.3.0":"2026-05-16T17:04:16.467Z","1.4.0":"2026-05-30T23:00:05.671Z","2.0.0":"2026-05-31T13:22:22.492Z","3.0.0":"2026-06-01T10:12:34.684Z","3.0.1":"2026-06-01T10:29:07.666Z","3.0.2":"2026-06-01T10:39:30.898Z","3.0.3":"2026-06-01T10:55:34.698Z"},"bugs":{"url":"https://github.com/aitoroses/agent-e2e-harness/issues"},"author":{"name":"Aitor Roses"},"license":"MIT","homepage":"https://github.com/aitoroses/agent-e2e-harness/tree/main/packages/harness#readme","keywords":["agent","e2e","mcp","playwright","testing","automation"],"repository":{"type":"git","url":"git+https://github.com/aitoroses/agent-e2e-harness.git","directory":"packages/harness"},"description":"Library-first Agent E2E Harness for seeded journeys, MCP proof loops, artifacts, and cleanup.","maintainers":[{"name":"grayfox","email":"aitor.oses@gmail.com"}],"readme":"# @agent-e2e/harness\n\nReusable TypeScript package for agent-driven E2E proof loops. Consumer apps use it to expose a local Dev MCP server, define seeded journeys, drive browser/API proof, collect artifacts, clean owned resources, and turn the same flow into CI.\n\nName map:\n\n- npm package: `@agent-e2e/harness`\n- adoption skill / repository: `agent-e2e-harness`\n- CLI binary: `agent-e2e`\n\n## Install\n\n```sh\nnpm install @agent-e2e/harness\n```\n\nInstall the adoption skill for the agent that will wire the app:\n\n```sh\nnpx skills add aitoroses/agent-e2e-harness --skill agent-e2e-harness --agent codex -y\n```\n\nThen invoke `$agent-e2e-harness` in the target app.\n\nAdd optional peers for the integrations you use:\n\n```sh\nnpm install -D @modelcontextprotocol/sdk playwright\n```\n\n`@modelcontextprotocol/sdk` is needed for the local Dev MCP HTTP server. `playwright` is needed for browser sessions. The Dev MCP is runtime-agnostic: TypeScript config and journeys load via jiti on Node `>=22`, Bun, or Deno — Bun is no longer required. (If you do run on Bun with the Testcontainers PostgreSQL provider, use Bun `>=1.3.14`; Bun `<=1.3.5` hangs in PostgreSQL startup.) Database clients, containers, queues, and other infrastructure dependencies belong in the consumer app that implements a stack provider.\n\nFor the common PostgreSQL case you do not have to hand-write that provider: import `createPostgresTestcontainersProvider` from `@agent-e2e/harness/testcontainers`. Its infra packages (`pg`, `@testcontainers/postgresql`, `testcontainers`) are optional peer dependencies loaded lazily, so they are only required if you actually use this subpath:\n\n```ts\nimport { createPostgresTestcontainersProvider } from \"@agent-e2e/harness/testcontainers\";\n\nconst postgres = createPostgresTestcontainersProvider({\n  database: \"app\",\n  username: \"app\",\n  password: \"app\",\n  schemaSql: SCHEMA_SQL,\n});\n```\n\n## Quickstart\n\nScaffold a minimal, runnable setup instead of copying boilerplate:\n\n```sh\nnpx agent-e2e init\n```\n\nThis writes `agent-e2e.config.ts` (a `defineAgentE2EConfig` with the sample journey wired in) and `journeys/sample.journey.ts` (one phase = state, one proof-light step = frame), then prints the exact next commands (`agent-e2e dev`, then `agent-e2e list` / `agent-e2e call run.begin …`). It is non-destructive — existing files are skipped, not overwritten, unless you pass `--force` — and takes an optional `agent-e2e init [targetDir]`. The generated config omits `browserSessions` so the Dev MCP auto-creates a Playwright session, and carries commented wiring for an explicit `createPlaywrightMcpBrowserSessionManager()` and a stack provider for when you outgrow the defaults. Point `baseUrl` at your app and grow the journey from there; the sections below show the full shapes.\n\n## Public Exports\n\n```ts\nimport { defineJourney } from '@agent-e2e/harness/core';\nimport { defineAgentE2EConfig } from '@agent-e2e/harness/dev-mcp';\nimport { runAgentE2EVerifyFromConfig } from '@agent-e2e/harness/verify';\nimport { createProcessStackProvider, createStackStartContext } from '@agent-e2e/harness/stack';\nimport { managedRuntime, attachedRuntime } from '@agent-e2e/harness/runtime';\nimport { createRunArtifactRecorder } from '@agent-e2e/harness/artifacts';\n```\n\nSubpaths are intentionally split:\n\n- `core` has no Playwright, MCP transport, consumer infrastructure, database, or app-framework imports.\n- `dev-mcp` exposes the local MCP control server and tool grammar.\n- `verify` runs configured journeys in CI and writes suite reports.\n- `playwright-mcp` owns browser sessions and browser forensics.\n- `stack` owns generic app/service lifecycle.\n- `runtime` owns Runtime Target helpers and Attached Runtime Mode diagnostics.\n- `artifacts` records and reads validation evidence.\n\n## Runtime Targets and Attached Runtime Mode\n\nRuntime Targets declare where journeys run or collect evidence. Use `managedRuntime(...)` for harness-owned local stacks and `attachedRuntime(...)` for an **Attached Runtime Target** whose infrastructure is externally owned.\n\n```ts\nimport { defineAgentE2EConfig } from '@agent-e2e/harness/dev-mcp';\nimport { attachedRuntime, managedRuntime, defineRuntimeCapabilities, defineRuntimeCapability } from '@agent-e2e/harness/runtime';\nimport { z } from 'zod/v4';\n\nexport default defineAgentE2EConfig({\n  journeys: [\n    defineJourney({\n      id: 'checkout:smoke',\n      profiles: [\n        { id: 'local', data: {}, isDefault: true, runtimeTargetId: 'local-dev' },\n        {\n          id: 'staging',\n          data: { baseUrl: 'https://staging.example.com' },\n          runtimeTargetId: 'staging',\n          runtime: { allowRunLifecycle: true, allowRunMutationTools: ['orders.create-owned'] }\n        }\n      ],\n      phases: [/* ... */]\n    })\n  ],\n  runtimeTargets: [\n    managedRuntime({ id: 'local-dev', label: 'Local dev stack' }),\n    attachedRuntime({\n      id: 'staging',\n      label: 'Staging',\n      status: async () => stagingStatusPacket(),\n      logs: async ({ serviceId, tail, level }) => readStagingLogs({ serviceId, tail, level }),\n      access: [{ id: 'browser-session', kind: 'browserStorageState' }],\n      capabilities: defineRuntimeCapabilities([\n        defineRuntimeCapability({\n          id: 'release.version',\n          title: 'Read release version',\n          description: 'Observe the deployed release version.',\n          risk: 'observation',\n          input: z.object({}),\n          output: z.object({ version: z.string() }),\n          run: async () => ({ version: await readReleaseVersion() })\n        })\n      ])\n    })\n  ]\n});\n```\n\nRun attached mode with `agent-e2e attached --target <id>`. Attached Runtime Mode does not own infrastructure lifecycle. Start or stop production, staging, preview, Kubernetes, or Docker Compose through product controls, then connect the harness. The attached MCP surface exposes `runtime.list`, `runtime.status`, `runtime.logs`, `runtime.access.status`, `runtime.capability.list`, and `runtime.capability.run`. `runtime.logs` requires `tail`, accepts optional `serviceId` and best-effort `level`, and writes an artifact. Runtime Capability risk values are `observation`, `runMutation`, and `runtimeMutation`; observation runs by default, runMutation requires Journey Profile opt-in, and runtimeMutation is blocked by default. Access Context status and Access Resolvers must not expose secret material in agent-visible responses; automatic `browser.open` authentication wiring is not part of this v1 attached runtime path unless product code supplies it.\n\n## Minimal Journey\n\n```ts\nimport { defineJourney } from '@agent-e2e/harness/core';\n\nexport const checkoutJourney = defineJourney({\n  id: 'checkout:happy-path',\n  title: 'Checkout happy path',\n  profiles: [\n    {\n      id: 'default',\n      label: 'Default buyer',\n      isDefault: true,\n      data: { email: 'buyer@example.com' }\n    }\n  ],\n  seed: async () => ({\n    environment: {\n      checked: [{ type: 'user', id: 'buyer@example.com' }],\n      created: [],\n      forbidden: [{ type: 'order', id: 'latest' }]\n    }\n  }),\n  phases: [\n    {\n      id: 'phase:checkout',\n      title: 'Checkout',\n      steps: [\n        {\n          id: 'step:place-order',\n          title: 'Place an order',\n          execute: async () => ({\n            status: 'passed',\n            observed: { confirmationVisible: true },\n            ownedResources: [{ type: 'order', id: 'order-123' }]\n          }),\n          proofs: [\n            {\n              id: 'proof:confirmation-visible',\n              title: 'Order confirmation is visible',\n              check: ({ observed }) => observed.confirmationVisible === true\n            }\n          ]\n        }\n      ]\n    }\n  ]\n});\n```\n\nThe seed prepares prerequisites. It should not pre-create the behavior the journey is proving.\n\n## Dev MCP Server\n\nCreate a conventional `agent-e2e.config.ts`:\n\n```ts\nimport { createResourceRegistry, defineResourceKind } from '@agent-e2e/harness/core';\nimport { defineAgentE2EConfig } from '@agent-e2e/harness/dev-mcp';\n\nconst orderKind = defineResourceKind({\n  kind: 'order',\n  create: async (input: { id: string }) => ({ kind: 'order', id: input.id }),\n  delete: async (resource: { kind: 'order'; id: string }) => {\n    await appApi.deleteOrder(resource.id);\n  }\n});\n\nexport default defineAgentE2EConfig({\n  stackProvider: appStackProvider,\n  journeys: [checkoutJourney],\n  resourceRegistry: createResourceRegistry([orderKind]),\n  verify: {\n    suites: [{ id: 'smoke', journeys: ['checkout:*'] }]\n  }\n});\n```\n\n`resourceAdapters: [orderResourceAdapter]` remains available for lower-level cleanup adapters that do not fit a typed resource kind.\n\nThen run the Dev MCP server through the package CLI:\n\n```json\n{\n  \"scripts\": {\n    \"dev:mcp\": \"agent-e2e dev\",\n    \"e2e:verify\": \"agent-e2e verify\"\n  }\n}\n```\n\nThe CLI creates the MCP harness, default Playwright browser sessions, `.agents-e2e/artifacts`, and signal handlers. jiti loads `agent-e2e.config.ts` (and the journey files it imports) directly on Node or Bun. Edits to those TypeScript modules hot-reload **in process**: `createReloadingHarnessSource` watches the config directory and re-evaluates the changed graph through jiti, so `journey.list`/`journey.inspect` reflect the edit on the next call behind the same MCP URL — no server restart, no MCP reconnect. (Caveat: jiti owns TypeScript; plain `.mjs`/`.js` journeys go through native ESM, which is globally cached by URL and does not in-process reload — keep journeys in `.ts`. `agent-e2e dev --watch` is an optional hard-restart fallback that disposes the managed stack on each restart.) It uses `127.0.0.1:3766/mcp` by default; set `AGENT_E2E_MCP_PORT` to override it. App URLs come from `stack.start` / `stack.status` service URLs, not from Dev MCP configuration.\n\n### Browser sessions\n\nBy default the Dev MCP auto-creates a Playwright-backed Browser Workbench, so you can leave `browserSessions` unset. To customize it (for example, to point sessions at a different artifact root), wire the public factory explicitly — this type-checks under strict mode:\n\n```ts\nimport { defineAgentE2EConfig } from '@agent-e2e/harness/dev-mcp';\nimport { createPlaywrightMcpBrowserSessionManager } from '@agent-e2e/harness/playwright-mcp';\n\nexport default defineAgentE2EConfig({\n  journeys: [checkoutJourney],\n  // Explicit wiring is supported; omit this field to use the same default.\n  browserSessions: createPlaywrightMcpBrowserSessionManager({ artifactRoot: '.agents-e2e/artifacts' })\n});\n```\n\nPass `browserSessions: false` to disable the Browser Workbench entirely (no Playwright launch). `DevMcpBrowserSessionController` method parameters are typed against the shared public input shapes (`BrowserActInput`, `BrowserInspectInput`, …) so a custom controller gets full call-site type-safety too.\n\n## Proof Loop\n\nDrive the app through a standard MCP client configured with the Dev MCP URL:\n\n```json\n{\n  \"mcpServers\": {\n    \"agent-e2e\": {\n      \"url\": \"http://127.0.0.1:3766/mcp\"\n    }\n  }\n}\n```\n\nThe proof loop uses these tools:\n\n```sh\nstack.start\nstack.list\nstack.status\nstack.logs\nstack.capability.list\nstack.capability.run\nrun.begin\nbrowser.open\nbrowser.sessions\nbrowser.inspect\nbrowser.refs\nbrowser.act\nbrowser.wait\nbrowser.eval\nbrowser.playwright\nbrowser.close\njourney.step\njourney.untilStep\njourney.phase\njourney.untilPhase\ncleanup.plan\nrun.reseed\nstack.stop\n```\n\n### Browser Workbench\n\nThe Browser Workbench (`browser.*`) is the browser-side exploration surface. `browser.inspect` is the standard evidence path: one call captures a compact path-oriented index, a screenshot, and console/network signals, and writes everything to `runs/<runId>/inspections/<seq>/{inspect.md,inspect.json,screenshot.png}`. It accepts `{ browserSessionId, target?, depth?, maxNodes? }` — omit `target` for the current page, pass `\"@<ref>\"` for UI forensics ref targeting, or pass a selector. Returns a compact index only; no inline tree or diagnosis.\n\n`browser.refs({ enabled })` toggles a live overlay that paints exactly the referencable nodes from the UI forensics tree — the same registry `browser.inspect` and `browser.act` use. The overlay is pointer-events:none, updates on DOM mutation/scroll/resize, never alters layout, and is captured in inspect screenshots when enabled. It is removed completely on disable, close, or teardown.\n\n`browser.act` accepts a `@ref` address or selector. Refs are best-effort stable per session (`@e1`, `@e2`, …); retired refs are not reused, and `browser.act(\"@ref\")` fails cleanly when a ref is stale. `browser.wait` handles explicit conditions. `browser.eval` and `browser.playwright` cover anything that needs custom page or Playwright code. Console and network facts come from `browser.inspect` signals — there are no separate console or network tools.\n\nRun artifact layout (all under `runs/<runId>/`):\n\n```text\nruns/\n  latest -> <runId>                 # local convenience symlink only\n  <runId>/\n    run-report.md\n    run-report.json                 # whole-run verdict + index\n    seed-manifest.json\n    timeline.json\n    metrics.json\n    owned-resources.json\n    cleanup-plan.json\n    cleanup.json\n    inspections/<seq>/\n      inspect.md\n      inspect.json\n      screenshot.png\n    journeys/<journeyId>/phases/<phaseId>/steps/<stepId>/\n      before.png\n      after.png | failure.png | skipped.png\n      inspect.md\n      inspect.json\n      step-report.json              # single agent-facing per-step report\n```\n\n`run-report.json` is the whole-run verdict and artifact index; there is no separate `result.json`, `index.json`, or `latest.json`. `step-report.json` is the single agent-facing per-step report (status, artifact paths, signals, failure info, raw payload under `execution`); it replaces the former `step-feedback.json`. Journey steps share the same `browser.inspect` evidence machinery as standalone inspections.\n\n**Agent UX principles.** The tool surface follows a small set of design rules: few generic tools over many narrow wrappers; tools observe facts, agents reason; tool output is a compact index and details live in artifacts; tool names are obvious and single-purpose; no legacy aliases. If a capability is cleanly expressible via `browser.eval` or `browser.playwright`, no narrow tool is added. `browser.inspect` exists because it packages a costly, repeated evidence pattern into one idempotent call. `browser.refs` exists because it connects live pixels to the UI forensics ref system that `browser.inspect` and `browser.act` share.\n\nThe journey time-travel grammar is `journey.step` (one step), `journey.untilStep` (a phase up to and including a target step), `journey.phase` / `journey.untilPhase` (a whole phase to its boundary). The UI-validation model treats each step as a distinct visual frame, so `journey.untilStep` makes every frame individually addressable: it runs a phase from its first step up to **and including** the target step and parks the managed state there, mirroring `journey.untilPhase`'s envelope (`results[]`, landed step at `results.at(-1)`). A step is addressed by its stable `stepId` within a `phaseId` (`{ runId, phaseId, stepId }`, the same address `journey.step` uses) — never a positional ordinal — and an unknown journey/phase/step returns the same coherent not-found envelope as the other journey tools.\n\nThe fixed stack grammar is intentionally small: `stack.start`, `stack.list`, `stack.status`, `stack.stop`, `stack.logs`, `stack.capability.list`, and `stack.capability.run`. `stack.start` accepts an optional caller-chosen `stackId` and returns the effective id. `stack.list` recovers running Stack Instances. `stack.status`, `stack.logs`, `stack.capability.run`, and `stack.stop` require an explicit `stackId`; there is no public stop-all tool. `run.begin` requires a valid `stackId` when a stack provider exists, creates the run's **Run Stack Binding**, and rejects `stackId` when no provider exists. `stack.status` is the unified stack-state packet: `StackStatusPacket.services` is the journey-facing runtime contract for dynamic URLs, stable service ids, endpoints, checks, warnings, errors, artifacts, and next actions. There are no native `stack.services`, `stack.health`, or `stack.env` tools in v1.\n\nA freshly-started server's very first `stack.start` can trip provider readiness (Docker image pull/daemon warmup, a cold dev-server compile) and fail even though an immediate retry succeeds. `stack.start` therefore retries the provider start/readiness path with a small bounded backoff — **2 attempts, 750ms apart** by default — so the first call self-heals. Each failed attempt fully tears its own handle down before retrying, so retries never leak or stack handles, and a deterministic precondition failure (for example a duplicate `stackId`) is surfaced immediately without retrying. Tune or disable it with `stackStart: { maxAttempts, backoffMs }` in `defineAgentE2EConfig` (`maxAttempts: 1` disables the retry). On a real failure — including retry exhaustion — `stack.start` always returns a coherent envelope (`{ status: \"failed\", code: \"stack-start-failed\", message }`), never a partial object missing `code`/`message`, so a client can branch on `status` without tripping over a missing key.\n\nWhen a provider starts, `start(ctx)` receives a `StackStartContext` with mode, stack id, serial worker identity, suite id when verify supplies one, and a stack artifact scope. Providers should use **Named Stack Allocations** by default: call `ctx.allocatePort(name)` or `ctx.allocateArtifactPath(name, { kind: \"file\" | \"directory\" })` for isolated ports, log paths, database paths, queues, and app artifact directories. The harness records those named allocations for stack evidence without requiring duplicate metadata in the provider handle or status packet. Product-specific helpers such as database or queue allocators stay outside the core stack contract.\n\n`stack.logs` is live diagnostics. It requires a `stackId`, one `serviceId`, a required `tail`, and an optional `stream` of `stdout`, `stderr`, or `combined`. `stack.logs` and `stack.capability.run` accept optional `runId` only to capture artifacts, and reject capture when the run is bound to a different `stackId`.\n\nStack-specific capabilities belong to the stack provider. Providers declare tools with `id`, `title`, `description`, `availableIn`, `risk`, mandatory Zod `input` and `output` schemas, and a handler. Dev MCP exposes them through `stack.capability.list` and `stack.capability.run`; `agent-e2e verify` receives only Verify Observation Tools: `availableIn: [\"dev\", \"verify\"]` and `risk: \"none\"`.\n\nUse returned artifact refs to inspect failures instead of relying on terminal scrollback.\n\nStarting `agent-e2e dev` only proves the server booted. A proof run requires tool calls. The CLI ships its own MCP client, so you do not have to hand-write one or register the server first — `agent-e2e list` and `agent-e2e call` are the canonical way to drive the running server:\n\n```sh\nagent-e2e list                                   # tool names exposed by the running server\nagent-e2e call stack.start '{\"stackId\":\"dev\"}'   # call a tool with JSON args (defaults to {})\nagent-e2e call run.begin '{\"journeyId\":\"my:journey\",\"stackId\":\"dev\"}'\n```\n\n`list`/`call` resolve the endpoint from the same config as `dev` (`AGENT_E2E_MCP_HOST/PORT/PATH`, or a full `AGENT_E2E_MCP_URL` override). `call` prints the tool's text result (JSON fallback), exits non-zero on a tool error, and uses a 300000ms per-call timeout (`AGENT_E2E_MCP_CALL_TIMEOUT_MS`) since `stack.start` exceeds the MCP SDK's 60s default. This replaces the previous \"copy a ~50-line mcp-call.ts client\" recipe.\n\nFor a fresh or remote agent session that prefers a portable dynamic client, `mcporter` is an alternative:\n\n```sh\nmcporter list http://127.0.0.1:3766/mcp --schema --json --allow-http\n\nmcporter call \\\n  --http-url http://127.0.0.1:3766/mcp \\\n  --allow-http \\\n  --tool stack.capability.list \\\n  --args '{}' \\\n  --output json\n```\n\nUse `--allow-http` for localhost HTTP MCP endpoints. Prefer `--http-url ... --tool ...`; dotted URL selector forms can fail for local MCP URLs.\n\n## CI Verify\n\nAfter the interactive proof passes, run the same configured journeys in CI:\n\n```sh\nagent-e2e verify\nagent-e2e verify --suite smoke\nagent-e2e verify --all-profiles --workers 4 --reporter github\n```\n\n`verify` loads `agent-e2e.config.ts`, starts worker-scoped Stack Instances lazily, creates an isolated Playwright context/page per selected run, performs per-run cleanup by default, and writes `report.json` plus `report.md` under `.agents-e2e/artifacts/_suites/<suite-id>/`. `--workers 4` means at most four active Verify Worker Stacks; selected runs execute serially inside each worker stack. Verify stack ids are generated as `worker-0`, `worker-1`, and so on, and stack-backed run reports include the bound `stackId`.\n\n`verify` runs crystallized journeys. It does not expose arbitrary Dev MCP exploration; journey code can only call verify-safe stack observation tools through `execution.stack.capability.run(...)`, so product-visible mutations still come from the app path, seed, journey steps, reseed, or cleanup.\n","readmeFilename":"README.md"}