{"_id":"tdd-enforcer","_rev":"34-2d58d9209705fdd1cd2f898f1f274cd5","name":"tdd-enforcer","dist-tags":{"latest":"0.5.0"},"versions":{"0.1.0":{"name":"tdd-enforcer","version":"0.1.0","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.0","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"06aba667f6eebccccb95f5a995864c6ab4306658","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.0.tgz","fileCount":20,"integrity":"sha512-4iwTMGaa2dGkXxM4wooUnN2Gk6UzRrI5R6cNxdElLI1is5G973sW3BmwH5OwV6qWsiM0aQ9To1PCAa0tqTBysw==","signatures":[{"sig":"MEUCIQDT+KY4hei5FtfDaqanihbWdT8CM/LOYXNEpIkCsM6DXAIgViX8s4J3zRatd/l3Vw75WgyjAEjx8A+IjaAuZe8Ofzw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":65972},"type":"module","gitHead":"20935e06ab89ba16ebe8d2f983fdb49d0fd1e6fe","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.0_1781587962684_0.003169252526167954","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"tdd-enforcer","version":"0.1.1","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.1","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"750514ac3ed2b160231ad79f578311427d76bc23","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.1.tgz","fileCount":21,"integrity":"sha512-FE/uCojO3wBzkbmjb4kjLkg+Zh37Tzn6XSKu1FklJaPE4oxDS9TNDcgVWL0Ixd8qXg904fY97zQWI1MsjdDWqA==","signatures":[{"sig":"MEYCIQCHwT/5Wl/iS4eFTRsmiSnt86qXFRu1q2kkc8gjrSpmrwIhAK3Geb0DIDlNWbAfmapNkeZSuehJSgXCeij0ej5FY2B4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":73333},"type":"module","gitHead":"ec24796a4b67a6b1e4d159c5a108c981feb56392","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.1_1781597114538_0.8164930499477601","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"tdd-enforcer","version":"0.1.2","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.2","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"58eccba2342022d310c87f2c63584c32a6cd6ed0","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.2.tgz","fileCount":21,"integrity":"sha512-itlb8j+NhH73hznhFe31rB0gDKtiB8fSrSctvUqRK+d6jBHJe0Fyb73ZyH6eGsQKi+l8jGtFyCP7Fzsv9tOMWg==","signatures":[{"sig":"MEUCIBpioAXKYHhPv37sC8vQregN4ZrYetEWjtAU/415BvaeAiEA85mo3jCMfDeBnLn/yB8RQG4WPE4LfywiVbnTyehYhss=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":73990},"type":"module","gitHead":"151919a457eb105b0e1337e801c665b6f34dd516","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.2_1781599281517_0.76772073372453","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"tdd-enforcer","version":"0.1.3","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.3","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"59f9d35e26baa089d94453a1fcabe1d874537695","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.3.tgz","fileCount":21,"integrity":"sha512-WYY5okU8uZeH01q724Ryj43UeZWJ6GOQO8JUG3Yj5ZiUtf6TV4IgGKvijDPiWToOQ+mp32ckSjmoPCQwinS7rw==","signatures":[{"sig":"MEQCIDPYUsNHRuCnkMyW+YPb/v8gXOyQ2c8CEqYx5o8v83kPAiBkbKfwS5ZAyKDKKHozToesUmNWOa8BrK4ctYPWXlfUYg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74237},"type":"module","gitHead":"a5ebd52381099dee86faedf5481ae74da9b012a3","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.3_1781601538518_0.33466193166112923","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"tdd-enforcer","version":"0.1.4","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.4","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"2c16a7a5d560cf94f83402e905493c98faa855c7","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.4.tgz","fileCount":21,"integrity":"sha512-RUoWPCI/U9y5t0qZzY+8xP6VtGOrlhBL6mjT2ovc6tOLQJHlKpOQkNlmk+Nt44vdhMyOiPwbShpyIpWYpmDuNg==","signatures":[{"sig":"MEYCIQCghUwBdGujC+nx6EHWnAl3aFRk32L6YOSDQ7Np8czd+wIhAMPUvniyzygapR8yLA6BPQYz969vf77uHzlU8Igyncr5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74255},"type":"module","gitHead":"479c56e4bea2fa3d5bc586a37bb31242bf2078b0","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.4_1781606262137_0.8098289574952908","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"tdd-enforcer","version":"0.1.5","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.5","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"ab9d095de60986b3161c88640759e16356647de6","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.5.tgz","fileCount":22,"integrity":"sha512-qeo4FguTss5w64botKoC5qyWlCPzgCs868ZyjqmRe/Ikw/uhq/v/ugu8M3Z17nXJUrsZlq/FG/w4ZzgyuVWEfA==","signatures":[{"sig":"MEQCIFV1pHJyKD/9Nx7xdOLHTO4872OpsdM9lVxpf19QlkNlAiBDW3+O+fDkWK+eGGU97U/j9BS83POwizvu3GkXVlqqXA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":76682},"type":"module","gitHead":"479c56e4bea2fa3d5bc586a37bb31242bf2078b0","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.5_1781607329634_0.26121625885399014","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"tdd-enforcer","version":"0.1.6","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.6","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"46c679da47409af86624f1493261729eb9b799d1","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.6.tgz","fileCount":22,"integrity":"sha512-35KHs/AvAjnXvgHSM/RJJD6zObZvocmMmtUfqftqfXxsTxspkmi/B6fdfrVhYP481HUoRvJf7VHZIl8uuIXyhw==","signatures":[{"sig":"MEQCICSclCBnVytucWd5Ipju6aOz4GdaftoFgX42J0HxjcONAiA5FyKCCoV6CsaTM8oUCpZVW2lPaL4WyqEoRp2ynAQrQw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":76485},"type":"module","gitHead":"a70a25248c9c4bcbafcd4530d1d262a4d13884ab","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.6_1781613186606_0.5227391778411521","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"tdd-enforcer","version":"0.1.7","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.7","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"e2dbc397f97b2c1c97bbf0e9e4c8d07effac5908","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.7.tgz","fileCount":22,"integrity":"sha512-qvykNoFKDkHWfKBDAV0+/txGENso8FTfvp5T0ua2ySCfaoBlNHO3KdcImfgVpd+Rmn80gVV8Vy/WnlITsChVYw==","signatures":[{"sig":"MEUCIGi/JF6YUhXE/4Y/OLtcfSEsFwKSlzH1g5NWwaFvkb84AiEAvnf/oCvau5L6Y7P5GdwM35jdEiDLl0U9dF+tr7hGB0w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78895},"type":"module","gitHead":"0bfe574eb795971f58fd48ba344287befd34f78b","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.7_1781617074399_0.40204761300171166","host":"s3://npm-registry-packages-npm-production"}},"0.1.8":{"name":"tdd-enforcer","version":"0.1.8","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.8","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"dad1c72123b18fe98908e085c8335546686d3f16","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.8.tgz","fileCount":22,"integrity":"sha512-qlS4WCXHW0cdk72dagmqvxRGYkEkMbE7qq1tjUYr9SW8zpzuF4UKJ5dn4JJbAH90F/coge7zKyXdFJp4P+gCcQ==","signatures":[{"sig":"MEUCIQChJmi7tQr2XTi2FG2t8JgXbuGh+MdZDNIiCO9PauEE2gIgJhYDax0KQAOpTC4NCIqPJ4Cl7a13Ia2jBVIEClIrqxA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78958},"type":"module","gitHead":"e6c0ef94bd5fb22a1b0dbdde86822a17c001e870","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.8_1781617842070_0.12377394599560887","host":"s3://npm-registry-packages-npm-production"}},"0.1.9":{"name":"tdd-enforcer","version":"0.1.9","keywords":["pi-package"],"_id":"tdd-enforcer@0.1.9","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"564a291e6b36e8fe9951fb5f56591023b3c32b80","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.1.9.tgz","fileCount":22,"integrity":"sha512-HKirfOgBjeBkI6MdMfBSmJy+WcST7mNzobcAst2KvzmwBNfaR3HiOJdy5O7vV0/amLQD6sFgd+kRZ/uTmYCbcQ==","signatures":[{"sig":"MEUCIQDJ92Vxao2/eFV/Z5Zcukfg7b05KzKCqR/2ik2bEEyxqgIgEj8jXfCUYFzvOb06M22WSX/BRRp88zNXGT5r1z+Dxqk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":80749},"type":"module","gitHead":"ad10af899823d2fcab0a8fa4b8cd9dd0f77f7ffd","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.1.9_1781621142811_0.8419620447909186","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"tdd-enforcer","version":"0.2.0","keywords":["pi-package"],"_id":"tdd-enforcer@0.2.0","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"497328ce3df8be2c71f0a673b22d01a51a3a5cf4","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.2.0.tgz","fileCount":23,"integrity":"sha512-wgAVowJHuGKuB+rj/lgvFcMkatyvPqt3trAM90EpJd8z+ejZCNQofyq+sxMug9CaegYMYJ6jGTzD8FtM9449lQ==","signatures":[{"sig":"MEUCIEKBjzPw6dESRgOqdXTgpl1BCWzBgKFdzk8VimCXFSrmAiEAo5dRuKiRas/yV/lgUjD1srDXupY+/J2aYR9q3+JkHXs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83231},"type":"module","gitHead":"c41d3fa418d4b0d2dc0f82793e73ec283ad55c87","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.2.0_1781668560305_0.5414585214341507","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"tdd-enforcer","version":"0.2.1","keywords":["pi-package"],"_id":"tdd-enforcer@0.2.1","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"3bc8b55b695b94810602592b28cc236f3dacfaab","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.2.1.tgz","fileCount":24,"integrity":"sha512-D5Ny7peXs7FVIRn+NQBKwTcV1hVJ9TZ2y4X1gElUI4UOXGUb4mTsqGBasliqzhURiBl5RECGUfqSOgUpGuwpDA==","signatures":[{"sig":"MEYCIQCTDMgJYg/zDfszp/AyT5Jsg5xWtKhuEdjKRR0rJSPLpAIhALCNzGGMNPKPiXnCzb4HKGzO7+jcDhd0Q0swWPvb2PTg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90801},"type":"module","gitHead":"7ee30ea722fab53f19c1a24061620eaa6c82beda","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.2.1_1781704436674_0.023102613876734512","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"tdd-enforcer","version":"0.2.2","keywords":["pi-package"],"_id":"tdd-enforcer@0.2.2","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"e9628457dcbf3cc22da472d19a10d6c46a469666","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.2.2.tgz","fileCount":24,"integrity":"sha512-119OL/qbOj442gg+Y5AQ0WVpzdcDdaaKNl788cWsrmcP/iGWw8uuRachqvw5+TCaKr/Gv/jjRoiqiJm7AbIi9g==","signatures":[{"sig":"MEUCIQCy9JjGBRssLuvOfUii2nrzUajtHBfPAJxDN4+bcLMkpwIgVHXxKBadeV0nczn6wv6w9YqQAoMHw8OQItbpNZDVZpY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":91022},"type":"module","gitHead":"12ab4a9469150d68a33a09f551151ae48db7dd9f","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.2.2_1781704561931_0.4144020248575411","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"tdd-enforcer","version":"0.2.3","keywords":["pi-package"],"_id":"tdd-enforcer@0.2.3","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"a9f0d14de3c314e158d6d85cbf4b23b4b0b538a9","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.2.3.tgz","fileCount":29,"integrity":"sha512-/ynttqEVRXLnvEeiq2MQsfUlFkf4fxff6QoWO27ViLqM2TVfH7qNDz0Qoz4SzXuK4KCORPGaVFlpetw5FHHCSQ==","signatures":[{"sig":"MEUCIQDRkbBbM2NdroJOrTSQnago1VU7EZXIHvAqHbNnoAfieAIgScCjYrPS+UsCGPS/Z+uNgAlFI7F7zMu6zR7l0D1jGcA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":155268},"type":"module","gitHead":"8f3464720b6f40aef8bc40c859877f18e5591091","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.2.3_1781776156176_0.9924815917193286","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"tdd-enforcer","version":"0.2.5","keywords":["pi-package"],"_id":"tdd-enforcer@0.2.5","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"30a557d6be9ef1ef03a08ec9a9db255e764bc5a5","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.2.5.tgz","fileCount":29,"integrity":"sha512-Ai+6n5IceNv4VE1ruw6Jp/F3Ngu5NTC4xAwiVuNGwVEk7SXbwoEuzWK6KXEmfb6Num1S0JeDwoM/keUXTuEWUA==","signatures":[{"sig":"MEQCICx3jcCeowwzY6b7/MGY+7sLwE35eXkbK78Mo9UBTRJeAiBFvXGRbFoz1jlsuzgU72rMrPQGTgE/tvsaC2xYNT6kiQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":156958},"type":"module","gitHead":"cfb943b588a7014b43f15509996dbbdb1bce56ad","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.2.5_1781852280432_0.5246004880060466","host":"s3://npm-registry-packages-npm-production"}},"0.2.6":{"name":"tdd-enforcer","version":"0.2.6","keywords":["pi-package"],"_id":"tdd-enforcer@0.2.6","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"3d8af48804163dbb52f72fed7122ca6dd41bfd76","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.2.6.tgz","fileCount":29,"integrity":"sha512-ZBBFzl6X6BcvcqGvxgdM9OwnVC/9eggBiXI6xb+eIfj9XSUS9a5lgarmI6sch7ACCL1kBlROY4CcxLyMp/I6Eg==","signatures":[{"sig":"MEYCIQCwF79sX0mKeUUH/TWBJ8YxG60s5B0By8EWLDYX0pEb4gIhAPTaQzMMlPrq7ADC/1PrJqL3RGOalzAEz0qBQAQLDaUB","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":157131},"type":"module","gitHead":"058749d6f0105e64e4a3e3cabc54a513c742fb2d","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.2.6_1781853314799_0.4603549126361557","host":"s3://npm-registry-packages-npm-production"}},"0.2.7":{"name":"tdd-enforcer","version":"0.2.7","keywords":["pi-package"],"_id":"tdd-enforcer@0.2.7","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"69e83190c62bfd55f27cb9b27851d21f4d36ffbf","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.2.7.tgz","fileCount":31,"integrity":"sha512-PDwXYNgFajU9CzEdtgzsfMSMgsvwI0bHbKRQVbCjxIuo1U7ilhFn6Ry6jjfc2rbbVjte5KGBW4LxhoCEK0kclg==","signatures":[{"sig":"MEUCIGuXjDRTRH0qbf2pRr3C6eJrIFiZBt7E2alqtYWzgDbZAiEAoWTZDhoXoB+olV21+DAzFqF6NIPvzVhL4H96DT7/B1Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":154921},"type":"module","gitHead":"81cab848c7bfb3c412f69e1ed322a4aa8bab8446","scripts":{"fmt":"biome format --write .","lint":"biome check .","test":"vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.2.7_1781932954471_0.8768195586760583","host":"s3://npm-registry-packages-npm-production"}},"0.2.8":{"name":"tdd-enforcer","version":"0.2.8","keywords":["pi-package"],"_id":"tdd-enforcer@0.2.8","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"0bf86a9869ffbff643d1231c2df15a53b3ee16f6","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.2.8.tgz","fileCount":31,"integrity":"sha512-MAtyCwRq7sEHtV2FuPBMYzQx1k2LXVoofIN9aisZbxFfzrAz20dpQynIS7UPDPTOnF5hYnn6i2hEXrSqziSd+g==","signatures":[{"sig":"MEYCIQD5MMvktqbgYzRRpkt5pgXbzhoZv/tS6G4y1aM9Z7faaAIhAOdHG15uNm5pllv5dSDeMf3HwK5OFWZeCK3DaTrPXFXf","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":158545},"type":"module","gitHead":"5645d6639b95a718dde1bb41c3db79a7d38b512b","scripts":{"fmt":"biome format --write .","lint":"biome check .","test":"vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.2.8_1781936717853_0.535795897330255","host":"s3://npm-registry-packages-npm-production"}},"0.2.9":{"name":"tdd-enforcer","version":"0.2.9","keywords":["pi-package"],"_id":"tdd-enforcer@0.2.9","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"8ce51ec105b13396567556de08a19132641f1adf","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.2.9.tgz","fileCount":31,"integrity":"sha512-mHHR6MUQCetp7XT+w5ntPqi8eD54CEkIjnsdL9/jSxxGdH1ZzIQrQS04VGy2BrPrPyXQQlDDRqa5URavVnBlkg==","signatures":[{"sig":"MEYCIQCV35GdltUskKqhL6dFMReE1EeFp76HBlTm6IbpjE2SqAIhAMPyFy02C5atcD4nxYvV+Oy7RwqWUdSuoVwwlH1xZjOu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":162445},"type":"module","gitHead":"44ae024b4d2e8f3fd1d6e81f32c06bdaf11f8ab4","scripts":{"fmt":"biome format --write .","lint":"biome check .","test":"vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.2.9_1781959085403_0.15208495383110465","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"tdd-enforcer","version":"0.3.0","keywords":["pi-package"],"_id":"tdd-enforcer@0.3.0","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"9b5bf33265ab2b152ce50c483fdd4910c31b560c","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.0.tgz","fileCount":31,"integrity":"sha512-qRE+bX3jLdnflvch3T9JSGl3+caWxrX8D9NcmKkHUCBUx9KSN0itklQ5do/SKcoEcIHtucL5N1zRHk3HoeaPNw==","signatures":[{"sig":"MEUCIGLGrZlxnC2lgzX34w9Y2/yvx28RtQA42/qVOgUA5l6MAiEA3bdCOM34pTB8AOTXB7YFuzJEpyGLr6SmWDrqgmAucpY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":163642},"type":"module","gitHead":"95ea733ffab1c280cd06ae66d2ef157c4fce7d1f","scripts":{"fmt":"biome format --write .","lint":"biome check .","test":"vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.0_1782049445668_0.5729762993299539","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"tdd-enforcer","version":"0.3.1","keywords":["pi-package"],"_id":"tdd-enforcer@0.3.1","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"ceaf88d5134b58aa08c8f77f41b9ae0ec5cc7212","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.1.tgz","fileCount":31,"integrity":"sha512-afJYZ2qisWhVEvzQ1Kx1w8Jha+EWc4/mkeziejcqM+pposhfgJ10sfq4xWvq8amxB+oQVAB4e7QrQTeR3NMvzw==","signatures":[{"sig":"MEQCIGojdwbBViDN7LTm49UjG48spiEWS/07uSZavcOjfhOpAiBZr4hwkC+gx+NcT4erX19dZVMskMcMLOZt51Cl0am/xQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":162296},"type":"module","gitHead":"4a6c3987303b487dd17f761c2edccf42382e354b","scripts":{"fmt":"biome format --write .","lint":"biome check .","test":"vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.1_1782054154073_0.16575282897727694","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"tdd-enforcer","version":"0.3.2","keywords":["pi-package"],"_id":"tdd-enforcer@0.3.2","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"548b7850c64920ee6862ebfa8a0b047733548ba4","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.2.tgz","fileCount":31,"integrity":"sha512-efiQ5H7hM7+vu02hWE6AlqxfNcO+KffMANMO4plNiZmcdV8uMeNv7H7obR1ssAJJm5tEfNXfhEhX4NUs3Lu96w==","signatures":[{"sig":"MEUCICr+gQNaAix17ey6Bt7W0kanIXx8yi7LvT17IpocnXduAiEA15B6SwZocc/Vk1jJwD3vl9+gUdy7yhOuAaw1u/cvYrw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":162591},"type":"module","gitHead":"32ffeca15f51dc985e8eb51822a1ffe895def5ac","scripts":{"fmt":"biome format --write .","lint":"biome check .","test":"vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.2_1782054762080_0.1765005282015908","host":"s3://npm-registry-packages-npm-production"}},"0.3.3":{"name":"tdd-enforcer","version":"0.3.3","keywords":["pi-package"],"_id":"tdd-enforcer@0.3.3","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"ebed2e30c34b2eeffbbce21b2dc0d2110842a11b","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.3.tgz","fileCount":29,"integrity":"sha512-/Y8DeiL5jN7H5yU/kwl4E1/BTLjMqs5DEFlpPZ6MJfRWbzWPPk2jWUjLrj9akTVY2RdIYITfQ7twHJZFhRVPOg==","signatures":[{"sig":"MEUCIHOj+KdfqgzoNAU+MQV5y8Yydiea2z4n0xNmByCxC7sPAiEAxsWD5rTnCGiFLHCmcDRh6eFoMikjPUZSsHazpSKrcG8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":151361},"type":"module","gitHead":"814da1c955e06700be380fae01745cef34e7f70a","scripts":{"lint":"biome check .","test":"vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.3_1782126689068_0.045515137437805775","host":"s3://npm-registry-packages-npm-production"}},"0.3.4":{"name":"tdd-enforcer","version":"0.3.4","keywords":["pi-package"],"_id":"tdd-enforcer@0.3.4","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"d04eb00866c74c10409f854bd1cb71b66514ce2d","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.4.tgz","fileCount":29,"integrity":"sha512-fm7+7PQd2BIH3Lpw8/Go5ybg6NrZDGJRXlphxWHIiM5uXudVr6aa7+kkuhrHQndRqa0KbS30z/JYcZweg6r3Mg==","signatures":[{"sig":"MEYCIQCvSY4omdJFsVhBpnXrfszppsY8Z8XXbggTctQJG0xnXgIhAMovFZgGJG2kvMt2i3ZdqgUBlv5NT6yOUDEU72scpBmk","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":170399},"type":"module","gitHead":"dae738afc36fac49d7949dd5cc4c41647a52cedb","scripts":{"lint":"biome check .","test":"vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"_npmVersion":"11.12.1","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.4_1782179055861_0.31589103361011883","host":"s3://npm-registry-packages-npm-production"}},"0.3.5":{"name":"tdd-enforcer","version":"0.3.5","keywords":["pi-package"],"author":{"name":"Cyclone1070","email":"hoangmai1070@gmail.com"},"license":"MIT","_id":"tdd-enforcer@0.3.5","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"homepage":"https://github.com/Cyclone1070/tdd-enforcer#readme","bugs":{"url":"https://github.com/Cyclone1070/tdd-enforcer/issues"},"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"e40dfab916ef8c104ba1a04ef1f2272cc3753934","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.5.tgz","fileCount":30,"integrity":"sha512-D8lbDI6k7lh6BKYTSx/Y1RyvN9QvMI1C08EIrr/wpp1zmrcPyCPKAkGNIdblU48UMDKRQBcELydeioFUtla/nw==","signatures":[{"sig":"MEQCIGcpfhj2X2k5n4KDtFfiaz0VyFZxqQPZqCq3FdnzPeTDAiBjys7yhaQqZStBnq7phMRK8byEwrnmHQDs158UDgozqQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":181188},"type":"module","gitHead":"0f7e753e3fa7ef368cbc820410e0836c77262ade","scripts":{"lint":"biome check .","test":"vitest run","check":"biome check --write . && vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"repository":{"url":"git+https://github.com/Cyclone1070/tdd-enforcer.git","type":"git"},"_npmVersion":"11.12.1","description":"TDD enforcer extension for the pi coding agent — enforces Red-Green-Refactor phases with file access restrictions and transition gates","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.5_1782217068870_0.6395110925496725","host":"s3://npm-registry-packages-npm-production"}},"0.3.6":{"name":"tdd-enforcer","version":"0.3.6","keywords":["pi-package"],"author":{"name":"Cyclone1070","email":"hoangmai1070@gmail.com"},"license":"MIT","_id":"tdd-enforcer@0.3.6","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"homepage":"https://github.com/Cyclone1070/tdd-enforcer#readme","bugs":{"url":"https://github.com/Cyclone1070/tdd-enforcer/issues"},"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"1e7743c083368c7ac8bd272d56696e0d28c7b9c2","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.6.tgz","fileCount":30,"integrity":"sha512-4TGiwe4wwHTdvUjzkq1t3PcIAkSVJl6DZ6jIixU7Ln7gOo3bD3zJQzxqS/7D7z2Msrnd6Q9d6Fr3kuI/thWe1Q==","signatures":[{"sig":"MEUCIBu3BOsxjl8jGfw18NEBpiYdhCJxzIJRHHpmrFeW/AVfAiEAsUwzwlssVBQRmvmWtyRCp4eR02SF654jgxEL9/u8GHI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":178461},"type":"module","gitHead":"6deedefcf329b7053b8772afcceb8726d13de31e","scripts":{"lint":"biome check .","test":"vitest run","check":"biome check --write . && vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"repository":{"url":"git+https://github.com/Cyclone1070/tdd-enforcer.git","type":"git"},"_npmVersion":"11.12.1","description":"TDD enforcer extension for the pi coding agent — enforces Red-Green-Refactor phases with file access restrictions and transition gates","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.6_1782295763983_0.005979414190056653","host":"s3://npm-registry-packages-npm-production"}},"0.3.7":{"name":"tdd-enforcer","version":"0.3.7","keywords":["pi-package"],"author":{"name":"Cyclone1070","email":"hoangmai1070@gmail.com"},"license":"MIT","_id":"tdd-enforcer@0.3.7","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"homepage":"https://github.com/Cyclone1070/tdd-enforcer#readme","bugs":{"url":"https://github.com/Cyclone1070/tdd-enforcer/issues"},"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"92078ea67ddd9f2549cc2849528a121563dc8be6","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.7.tgz","fileCount":30,"integrity":"sha512-OpKRAI+KjtXynGvojoB0nnKDOKly3wqzpiwV/y4mr5b/ObBgvuu7459+lLd93XQuhUHVUEsTN7WCnGv7cwxr0A==","signatures":[{"sig":"MEYCIQDHbUpmcEvQmdSVlf8aXCLFZOvLu5Ynh+ETRylD882qIAIhAPbYByZhg3jGxO8iyiAHK2Eocj9qvAZgUtyUVGo4Hpnb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":182570},"type":"module","gitHead":"e0dd337f11d101ca3cae3a7f1f2cd69ada9ce14a","scripts":{"lint":"biome check .","test":"vitest run","check":"biome check --write . && vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"repository":{"url":"git+https://github.com/Cyclone1070/tdd-enforcer.git","type":"git"},"_npmVersion":"11.12.1","description":"TDD enforcer extension for the pi coding agent — enforces Red-Green-Refactor phases with file access restrictions and transition gates","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.7_1782954191584_0.3135119909602977","host":"s3://npm-registry-packages-npm-production"}},"0.3.8":{"name":"tdd-enforcer","version":"0.3.8","keywords":["pi-package"],"author":{"name":"Cyclone1070","email":"hoangmai1070@gmail.com"},"license":"MIT","_id":"tdd-enforcer@0.3.8","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"homepage":"https://github.com/Cyclone1070/tdd-enforcer#readme","bugs":{"url":"https://github.com/Cyclone1070/tdd-enforcer/issues"},"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"0e44fd6a26f73a92f61eabd1791c68ecf03cc3d0","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.8.tgz","fileCount":30,"integrity":"sha512-MP7aYCWw2nGFIOtYRfRJDlJpUWgKMd2CjCXV16k/kkSmdraVWIqRpsueiTseDUc9ix3B+pbEEtgiO7LVJtB/aQ==","signatures":[{"sig":"MEUCICIVuTjW+JfhR8Y1/40ZWK1Bm6I14GWT3FUTVCiQPh4pAiEAyKExJODupLy5JeIcBgc84mA2b0WNo92PHzD1nVqBwQQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":182572},"type":"module","gitHead":"3fc4dab0321fd90ebfbeb9ecf4f60d534b268fc4","scripts":{"lint":"biome check .","test":"vitest run","check":"biome check --write . && vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"repository":{"url":"git+https://github.com/Cyclone1070/tdd-enforcer.git","type":"git"},"_npmVersion":"11.12.1","description":"TDD enforcer extension for the pi coding agent — enforces Red-Green-Refactor phases with file access restrictions and transition gates","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.8_1782954611329_0.5285959515766743","host":"s3://npm-registry-packages-npm-production"}},"0.3.9":{"name":"tdd-enforcer","version":"0.3.9","keywords":["pi-package"],"author":{"name":"Cyclone1070","email":"hoangmai1070@gmail.com"},"license":"MIT","_id":"tdd-enforcer@0.3.9","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"homepage":"https://github.com/Cyclone1070/tdd-enforcer#readme","bugs":{"url":"https://github.com/Cyclone1070/tdd-enforcer/issues"},"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"95cf6a10cbde8b75232ff7f5595faac91925a4c9","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.9.tgz","fileCount":32,"integrity":"sha512-YFa1J1hgyA3/5xMNBEgQ5Q7fXEZajU5EKHGGp+7IjKgqUeGe6TV7+mjX9LoctydETYn5UGDawyYKvlVnKY52Yw==","signatures":[{"sig":"MEUCIQDNGdwNGm8fFy7P8b6T3N7j0tuc9hOVb4g0jFAPX8/QIwIgYdyigjEpN1SZde6Gff9vzJHOfhlEFzHUQgXc2Gzi4Sg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":210050},"type":"module","gitHead":"b1f71422759a7a7dd04dcd8d04b99b3c9cc341a7","scripts":{"lint":"biome check .","test":"vitest run","check":"biome check --write . && vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"repository":{"url":"git+https://github.com/Cyclone1070/tdd-enforcer.git","type":"git"},"_npmVersion":"11.12.1","description":"TDD enforcer extension for the pi coding agent — enforces Red-Green-Refactor phases with file access restrictions and transition gates","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.9_1785131116672_0.6831357510786389","host":"s3://npm-registry-packages-npm-production"}},"0.3.10":{"name":"tdd-enforcer","version":"0.3.10","keywords":["pi-package"],"author":{"name":"Cyclone1070","email":"hoangmai1070@gmail.com"},"license":"MIT","_id":"tdd-enforcer@0.3.10","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"homepage":"https://github.com/Cyclone1070/tdd-enforcer#readme","bugs":{"url":"https://github.com/Cyclone1070/tdd-enforcer/issues"},"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"2b4671b0505ef98a94b17d558ffcbbe9063f6cad","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.3.10.tgz","fileCount":30,"integrity":"sha512-44l948mBb7zzJYTVohPgyrzuHCqvrrIQGkJmmxsCkwUnik/yp5frykx3seufX515dYAeAdbU6UsQ3zLsMTvSbg==","signatures":[{"sig":"MEYCIQCTQOt6/Fj8M6Hy2z+4LNwwXOApLikN3ou1RebnKiFIUgIhANXkDpeh6M2DnKrulM7if+xv/h+HrmlqIUqTtXzbHCPT","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":182762},"type":"module","gitHead":"c52bc7d21f9ad3cc1a3ce39385ba372dc05002c8","scripts":{"lint":"biome check .","test":"vitest run","check":"biome check --write . && vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"repository":{"url":"git+https://github.com/Cyclone1070/tdd-enforcer.git","type":"git"},"_npmVersion":"11.12.1","description":"TDD enforcer extension for the pi coding agent — enforces Red-Green-Refactor phases with file access restrictions and transition gates","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.3.10_1785506891970_0.6187402546466723","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"tdd-enforcer","version":"0.4.0","keywords":["pi-package"],"author":{"name":"Cyclone1070","email":"hoangmai1070@gmail.com"},"license":"MIT","_id":"tdd-enforcer@0.4.0","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"homepage":"https://github.com/Cyclone1070/tdd-enforcer#readme","bugs":{"url":"https://github.com/Cyclone1070/tdd-enforcer/issues"},"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"dist":{"shasum":"cbf7b4499d5f547640c3ba7990ae6c6e6ea15d83","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.4.0.tgz","fileCount":32,"integrity":"sha512-4gq/HoAdsaieOGuLEFd9VfgotTgGh1bJ8a95Qp2MMSWoHR+BwyRqS7xJ6Ri518uUN2m+qXu0UAkizUIvE7MAzw==","signatures":[{"sig":"MEYCIQCCEC6V8GtZG05nAfMcmwaI/YRV1Psrbn9h8eMEeXM0KgIhAI9vM0RlcSYd+jXvqIFAAO0P2AtK+KuRKucsdfo3i/oG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIBewHykLnSHnDdqTZ0fojgu8WS0xP1cUxZALAKpp6UX9AiEAnGRUbRtkeYAqkTAi5k+Vt2oa069qbzo8Yy9VVsPXEMM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":189561},"type":"module","gitHead":"ee5d442bb1d9bb4e3c250fc55cad9d408c139819","scripts":{"lint":"biome check .","test":"vitest run","check":"biome check --write . && vitest run","lint:fix":"biome check --write ."},"_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"repository":{"url":"git+https://github.com/Cyclone1070/tdd-enforcer.git","type":"git"},"_npmVersion":"11.12.1","description":"TDD enforcer extension for the pi coding agent — enforces Red-Green phases with file access restrictions and transition gates","directories":{},"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"tmp":"tmp/tdd-enforcer_0.4.0_1790085936956_0.36680957049952423","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"pi":{"skills":["./skills"],"extensions":["./adapters/pi/index.ts"]},"_id":"tdd-enforcer@0.5.0","dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"bugs":{"url":"https://github.com/Cyclone1070/tdd-enforcer/issues"},"dist":{"shasum":"dc9843b6d2cba6cb9a2e91aee0f8ee264613fd36","tarball":"https://registry.npmjs.org/tdd-enforcer/-/tdd-enforcer-0.5.0.tgz","fileCount":47,"integrity":"sha512-NdT7LY30+p87M0AS6uWrRz9ovNhACU7ccceUX37EhAU4tM8FJQ06iftkyiLwS3Y+Qt/Mfh2ha43OV8XGH8QV+A==","signatures":[{"sig":"MEUCIDfPK+kTNt5+mkRKl6oTXqKhk86QWAdJH4J1cmRswNdwAiEAh6KhTscMe5sQ4X27KJ5i5Vmk/m/hIPgpjrZxK3ca+Ik=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCTXJGmHXheYthL+NDFNCN759+JpR97o59E1eW0UFkeYwIgKIQhzTsq5/o+6JkzZMoVZZNwj7E7wwhV3LUgo5AVrLk="}],"unpackedSize":384402},"main":"./dist/dsh/plugin.js","name":"tdd-enforcer","type":"module","author":{"name":"Cyclone1070","email":"hoangmai1070@gmail.com"},"gitHead":"c4b3b5baa3b122794514f5282501f3b08ce7c383","license":"MIT","scripts":{"lint":"biome check .","test":"vitest run","build":"node scripts/build-dsh.mjs","check":"biome check --write . && vitest run","prepare":"npm run build","lint:fix":"biome check --write .","preflight":"node scripts/preflight-dsh.mjs"},"version":"0.5.0","_npmUser":{"name":"cyclone1070","email":"hoangmai1070@gmail.com"},"homepage":"https://github.com/Cyclone1070/tdd-enforcer#readme","keywords":["pi-package","dsh-plugin"],"repository":{"url":"git+https://github.com/Cyclone1070/tdd-enforcer.git","type":"git"},"_npmVersion":"11.12.1","description":"TDD enforcer plugin — enforces Red-Green phases with file access restrictions and transition gates, for the pi coding agent and the DeepSeek Harness","directories":{},"maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"_nodeVersion":"26.0.0","dependencies":{"picomatch":"^4.0.4"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3","esbuild":"^0.27.7","typebox":"^1.2.16","@types/node":"^25.9.3","@biomejs/biome":"^2.5.0","@earendil-works/pi-coding-agent":"^0.79.6"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/tdd-enforcer_0.5.0_1790600793881_0.38499274020419194"}}},"time":{"created":"2026-06-16T05:32:42.514Z","modified":"2026-09-28T13:06:34.246Z","0.1.0":"2026-06-16T05:32:42.807Z","0.1.1":"2026-06-16T08:05:14.673Z","0.1.2":"2026-06-16T08:41:21.699Z","0.1.3":"2026-06-16T09:18:58.642Z","0.1.4":"2026-06-16T10:37:42.270Z","0.1.5":"2026-06-16T10:55:29.779Z","0.1.6":"2026-06-16T12:33:06.742Z","0.1.7":"2026-06-16T13:37:54.526Z","0.1.8":"2026-06-16T13:50:42.201Z","0.1.9":"2026-06-16T14:45:42.943Z","0.2.0":"2026-06-17T03:56:00.451Z","0.2.1":"2026-06-17T13:53:56.854Z","0.2.2":"2026-06-17T13:56:02.084Z","0.2.3":"2026-06-18T09:49:16.330Z","0.2.4":"2026-06-18T10:01:09.557Z","0.2.5":"2026-06-19T06:58:00.570Z","0.2.6":"2026-06-19T07:15:14.935Z","0.2.7":"2026-06-20T05:22:34.590Z","0.2.8":"2026-06-20T06:25:17.983Z","0.2.9":"2026-06-20T12:38:05.552Z","0.3.0":"2026-06-21T13:44:05.825Z","0.3.1":"2026-06-21T15:02:34.221Z","0.3.2":"2026-06-21T15:12:42.252Z","0.3.3":"2026-06-22T11:11:29.225Z","0.3.4":"2026-06-23T01:44:15.994Z","0.3.5":"2026-06-23T12:17:49.053Z","0.3.6":"2026-06-24T10:09:24.126Z","0.3.7":"2026-07-02T01:03:11.744Z","0.3.8":"2026-07-02T01:10:11.504Z","0.3.9":"2026-07-27T05:45:16.838Z","0.3.10":"2026-07-31T14:08:12.110Z","0.4.0":"2026-09-22T14:05:37.039Z","0.5.0":"2026-09-28T13:06:34.045Z"},"bugs":{"url":"https://github.com/Cyclone1070/tdd-enforcer/issues"},"author":{"name":"Cyclone1070","email":"hoangmai1070@gmail.com"},"license":"MIT","homepage":"https://github.com/Cyclone1070/tdd-enforcer#readme","keywords":["pi-package","dsh-plugin"],"repository":{"url":"git+https://github.com/Cyclone1070/tdd-enforcer.git","type":"git"},"description":"TDD enforcer plugin — enforces Red-Green phases with file access restrictions and transition gates, for the pi coding agent and the DeepSeek Harness","maintainers":[{"name":"cyclone1070","email":"hoangmai1070@gmail.com"}],"readme":"# tdd-enforcer\n\n**Lock files per TDD phase. Gate transitions on test outcomes.**\n\n[![CI](https://github.com/Cyclone1070/tdd-enforcer/actions/workflows/ci.yml/badge.svg)](https://github.com/Cyclone1070/tdd-enforcer/actions/workflows/ci.yml)\n\n[![npm version](https://img.shields.io/npm/v/tdd-enforcer.svg)](https://www.npmjs.com/package/tdd-enforcer)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n---\n\n<img width=\"741\" height=\"586\" alt=\"Screenshot 2026-06-26 at 20 52 02\" src=\"https://github.com/user-attachments/assets/4bba490d-ab94-43b1-8c2a-552b34374aee\" />\n\n---\n\n## Features\n\n- **Phase-locked file access** — prevents the agent from modifying test files in GREEN and implementation files in RED\n- **Guards every tool that can write** — `write` and `edit` are blocked before they run when the path is locked. `bash`, MCP tools, and any other tool get a snapshot-and-revert bracket, so a locked file that a command touches is restored afterwards\n- **Background commands included** — a backgrounded `bash` job is diffed and reverted when the job settles, not when the tool returns\n- **Automatic transition gates** — advancing to the next phase requires tests to fail (RED→GREEN) or pass (GREEN→RED). Misconfigured or broken transitions are rejected\n- **Safe rollback** — if the previous phase's work was wrong, reverting discards all current changes and restores the exact working tree from before that phase\n- **Stays out of your way** — TDD enforcement is opt-in. Disable anytime to unlock all files\n- **Version-controlled config** — `.tdd/rules.json` lives in your repo alongside the code, so the whole team shares the same rules\n- **Two hosts** — the same engine drives the pi coding agent and the DeepSeek Harness (DSH)\n\nTDD state lives in `.tdd/` at the project root. Projects that already have `.pi/tdd/` keep working: that layout is still read, and it stays locked while TDD is active. If both exist, `.tdd/` wins and the plugin warns you to finish the migration.\n\n### Moving a project from `.pi/tdd` to `.tdd`\n\nEach layout keeps its own state and its own private git history, so migrating is a directory move with TDD turned off, then turning it back on:\n\n1. Turn TDD off\n2. `mv .pi/tdd .tdd`\n3. Turn TDD back on\n\n`rules.json`, `state.json` (enabled flag and phase) and the snapshot history in `.git/` all carry over unchanged. Step 3 takes the snapshot that re-records the state directory in the private repo — until that happens the repo still tracks the old `.pi/tdd` paths, and a rollback would restore them. Creating an empty `.tdd/` instead of moving starts a fresh RED baseline with no history and leaves `.pi/tdd` behind, which is exactly the both-directories warning `tdd_status` reports.\n\n---\n\n## Why Red-Green only?\n\nThe **REFACTOR** phase has been left out on purpose.\n\nLLM agents do their best structural work during GREEN. Once the tests pass, refactor phase is often treated as a formality and is usually skipped. The gate can only verify that tests pass, so it cannot verify that refactoring actually happened. A phase nothing can enforce degenerates into ceremony, and the cycle becomes RED→GREEN→RED with extra steps. With poor context or small models REFACTOR phase is also used as a TDD bypass tool since it doesn't enforce any file lock.\n\nRemoving it keeps the loop honest:\n\n- RED locks implementation files, GREEN locks test files. Both phases have hard, testable rules\n- Every transition has a real gate — tests must fail to enter GREEN, and pass to leave it\n- Cycles stay small, so `previous_tdd_phase` is cheap when assumptions turn out wrong\n\n### Refactor deliberately, not automatically\n\nStructure changes are best done as a separate, conscious pass over a green suite — once in a while, not after every cycle:\n\n1. Finish a cycle or a feature with the tests passing\n2. Turn TDD off (`/tdd-off` in DSH, `/tdd:off` in pi) to unlock all files\n3. Ask for a focused refactor pass — tests stay green, behaviour unchanged — or do it yourself\n4. Turn TDD back on when you are ready to continue\n\nThe test suite is the safety net; the decision to refactor is yours.\n\n---\n\n## Setup\n\n### 1. Install\n\nFor the pi coding agent:\n\n```bash\npi install npm:tdd-enforcer\n```\n\nFor the DeepSeek Harness, add the package to the profile — the Plugins page in the web UI, or from a terminal:\n\n```bash\nnpm run build                                  # bundles dist/dsh from the checkout\ndsh plugin --profile web add /path/to/tdd-enforcer\n```\n\nInstalling through the agent's `plugin_manager` tool (`action: install_bundle`, `target: <package path>`) does the same thing.\n\nThe harness loads the prebuilt bundle (`dist/dsh/plugin.js`), so build before installing. **Restart DSH after installing or after rebuilding**: Node caches package resolution and imported modules per process, so a running host keeps serving the previous copy of the plugin.\n\n### 2. Ask the agent to set up TDD\n\nTell the agent to configure TDD for your project, using the `tdd-enforcer` skill to create `.tdd/rules.json` with the right file globs and test commands for your stack.\n\n### 3. Enable TDD\n\nOnce configured, run:\n\n```\n/tdd-on          # DSH\n/tdd:on          # pi\n```\n\n### Config reference\n\n`.tdd/rules.json` fields (created by the agent, not manually):\n\n| Field | Description |\n|-------|-------------|\n| `blockedInRed` | Globs the agent **cannot** touch in RED phase (implementation files) |\n| `blockedInGreen` | Globs the agent **cannot** touch in GREEN phase (test files) |\n| `!` prefix | Exclusion: carves out subsets from a block (e.g. co-located test files) |\n| `testCommands` | Commands run in parallel for gate checks. Exit 0 = pass, non-zero = block. Use `&&` inside a single entry to chain dependent steps |\n| `timeoutSeconds` | Test timeout per command (default: 120) |\n\n---\n\n## Usage\n\n### User commands\n\npi registers them with a colon, DSH forbids that character in command names, so both spellings are shown.\n\n| Command (DSH / pi) | Description |\n|---------|-------------|\n| `/tdd-on` `/tdd:on` | Enable TDD enforcement |\n| `/tdd-off` `/tdd:off` | Disable TDD enforcement, all files become free |\n| `/tdd-status` `/tdd:status` | Show phase, blocked globs, test commands |\n| `/tdd-reset` `/tdd:reset` | **Destructive**: nukes all snapshot history, resets to RED (disabled) |\n| `/tdd-red` `/tdd-green` `/tdd:red` `/tdd:green` | Skip to a given phase (auto-enables, no gate checks) |\n\n### Agent tools\n\n| Tool | When to use | Effect |\n|------|-------------|--------|\n| `next_tdd_phase` | Current phase work is complete | Runs allowlist check + gate test, snapshots state, advances phase|\n| `previous_tdd_phase` | Previous phase work was wrong | **Discards all current-phase changes**, restores working tree to previous snapshot |\n| `tdd_status` | Check current enforcement state | Returns phase, blocked globs, test commands |\n\n---\n\n## How it works\n\nUses a **private git repository** at `.tdd/.git/` (separate from your project's real git history) to detect locked-file changes, revert invalid modifications, and track state across phase transitions.\n\n```\n                tests fail                  tests pass\n     ┌──────┐   (gate check)    ┌────────┐  (gate check)\n     │ RED  │ ─────────────────▶│ GREEN  │ ───────────────┐\n     │(test)│                   │ (impl) │                │\n     └──────┘                   └────────┘                │\n        ▲                                                 │\n        └─────────────────────────────────────────────────┘\n                         new cycle\n```\n\nEvery phase transition runs two validations before advancing:\n\n1. **Allowlist check** — scans working tree changes against the phase's blocked globs. If any locked file has been modified, the transition is rejected with the violating paths listed\n2. **Gate check** — runs `testCommands` in parallel. The required outcome depends on the transition:\n   - RED→GREEN: all commands must fail (a passing test suite means there's no failing test to justify moving to GREEN)\n   - GREEN→RED: all commands must pass\n\nIf both checks pass, the working tree is snapshotted and the phase advances.\n\n### File-level enforcement\n\nThe two hosts expose different interception points, and each adapter uses the strongest one available.\n\n**pi** hooks `tool_call` / `tool_result` for `write`, `edit`, and `bash`:\n\n- **`write` / `edit`** — the target path is checked against the current phase's blocked globs before the tool executes. Locked writes are rejected with an error message\n- **`bash`** — the working tree is snapshotted before the command runs. After it finishes, the diff is compared against the snapshot. Locked-file modifications are reverted and the command output is amended with a warning listing them\n\n**DSH** splits the same idea across the tool pipeline:\n\n- **`write` / `edit`** — a synchronous tool guard denies a locked path before the tool body runs. Guards are monotonic: no later listener can turn a denial back into permission\n- **`bash`, MCP tools, and unknown tools** — a snapshot is taken before the call and diffed after it. A locked file that changed and existed before the call is restored to its pre-call content; a locked file the call created is removed. Everything the phase allows is kept. The call comes back as an error listing reverted files, retained changes, and the original tool output\n- **background `bash`** — the snapshot is handed to the job id and settled by a `ctx.jobs` subscription. Since the tool already returned, the revert is reported as a notice on a later tool result\n- **read-only tools** — skipped entirely, so they add no overhead\n\nIn both hosts the revert is path-scoped by the phase rules: only changed-and-locked files are touched, so concurrent changes are never clobbered.\n\nBoundaries worth knowing: the snapshot covers the project directory only, so writes outside the repo are not reverted, and a file written by an MCP server's own separate process cannot be attributed to the call. `testCommands` are executed by the plugin in the project root, not through the host's sandbox.\n\n### Rollback mechanics\n\nEach phase transition creates a labeled commit in a private git repository at `.tdd/.git/`. Calling `previous_tdd_phase`:\n\n1. Confirms HEAD is a TDD snapshot (commit message carries a valid phase label)\n2. Hard-resets the working tree to discard uncommitted changes\n3. Soft-resets HEAD~1 to pop the snapshot\n4. Sets the phase back\n\nIf HEAD is not a TDD snapshot, the private repo is nuked and rebuilt with a clean RED baseline instead.\n\nSince TDD owns its own git repo, rollback doesn't touch the project's real git history at all.\n\n### State recovery\n\n`state.json` is read leniently: missing files, malformed JSON, and unknown phase values never crash the extension. A valid `state.json` phase wins; otherwise the phase is recovered from the last TDD commit message in the private repo (`.tdd/.git/`, or `.pi/tdd/.git/` for the legacy layout) (`tdd: red`, `tdd: green`). A root commit with no parent is treated as a fresh baseline in RED (disabled).\n\nIf the private git repo itself is unusable — git commands throw, or HEAD is not a TDD snapshot — the history is treated as corrupt: the private repo is nuked and re-initialised with a clean RED baseline. `previous_tdd_phase` follows the same rule, so a corrupt history resets instead of failing.\n\n---\n\n## Development\n\n```bash\nnpm install\nnpm run check     # biome + vitest\nnpm run build     # bundle the DSH plugin into dist/dsh\n```\n\n### Project structure\n\n```\ntdd-enforcer/\n├── engine/                  # Framework-agnostic core\n│   ├── types.ts             # Phase, Config, Transition types\n│   ├── paths.ts             # .tdd layout + .pi/tdd fallback resolution\n│   ├── config.ts            # Load & validate rules.json\n│   ├── state.ts             # Load/save/recover phase state\n│   ├── enforce.ts           # Glob-based file allowlist checks\n│   ├── transition.ts        # Gate checks (test failure/pass per transition)\n│   ├── orchestrate.ts       # advancePhase / revertPhase orchestration\n│   ├── git.ts               # Private git repo for snapshots & diff\n│   ├── log.ts               # Append-only log with line cap\n│   └── prompts.ts           # Phase-specific agent nudges\n├── adapters/\n│   ├── shared/\n│   │   └── actions.ts       # next/previous phase + status, host-neutral\n│   ├── pi/                  # pi extension adapter\n│   │   ├── index.ts         # Extension entry: commands (tdd:on/off/status/reset/jump)\n│   │   ├── hooks.ts         # Intercept write/edit/bash tool calls & results\n│   │   └── tools.ts         # Agent tools: next_tdd_phase, previous_tdd_phase, tdd_status\n│   └── dsh/                 # DSH host plugin adapter\n│       ├── index.ts         # apply(): guard, tool pipeline listeners, registrations\n│       ├── enforcement.ts   # Tool guard + snapshot-and-revert bracket (+ background jobs)\n│       ├── commands.ts      # tdd-on/off/status/reset/red/green\n│       ├── tools.ts         # The same three agent tools\n│       ├── skill.ts         # Registers the shipped SKILL.md at runtime\n│       └── types.ts         # Minimal structural types for the host surface\n├── skills/\n│   └── tdd-enforcer/\n│       └── SKILL.md         # Agent instructions for TDD workflows\n├── scripts/\n│   └── build-dsh.mjs        # Bundles adapters/dsh into dist/dsh\n├── cordis.patch.yml         # DSH bundle manifest (inserts the plugin row)\n└── package.json\n```\n\n- `engine/` — pure logic, zero host dependencies. Testable in isolation\n- `adapters/shared/` — phase actions both adapters call, so host wiring stays thin\n- `adapters/pi/` — pi-specific wiring: commands, hooks, agent tools\n- `adapters/dsh/` — DSH-specific wiring: tool guard, tool pipeline listeners, commands, tools\n- `skills/tdd-enforcer/` — agent instructions; DSH registers this file itself, so nothing is copied into your project\n\n---\n\n## License\n\n[MIT](LICENSE)\n","readmeFilename":"README.md"}