{"_id":"@code-fixer-23/pi-form-components","_rev":"12-78e9123cb23985ddb64e8f800beec8d1","name":"@code-fixer-23/pi-form-components","dist-tags":{"latest":"3.1.6"},"versions":{"2.0.0":{"name":"@code-fixer-23/pi-form-components","version":"2.0.0","_id":"@code-fixer-23/pi-form-components@2.0.0","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"da312c07b818fa5a4508adfb452aa581c2394517","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-2.0.0.tgz","fileCount":11,"integrity":"sha512-Y2KIoKBErUJYlndic0gLPl6JKjTiaBf5QfPOPiOjpMVFgT5WVJ/zzPrOW/QnvQHZ/eVWfAhMfuKy6osoK567fw==","signatures":[{"sig":"MEYCIQCEMoZMd3PA8YUtQ2ALcCqdABl3w6W+oOb2aS+tIfKOVQIhAIWrStSpvkZB/SxreksFJFiS8c45N3jvQALnZoSjzfSn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":256784},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":"https://github.com/louiss0/pi-packages","directories":{},"_nodeVersion":"26.0.0","dependencies":{"tslib":"^2.3.0","@earendil-works/pi-tui":"^0.75.3","@earendil-works/pi-coding-agent":"^0.75.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.0","vitest":"^4.1.4","vite-plugin-dts":"^4.5.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_2.0.0_1779729862881_0.39725312406074864","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@code-fixer-23/pi-form-components","version":"2.0.1","_id":"@code-fixer-23/pi-form-components@2.0.1","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"d71e871af56b2ab00ec6c5ef41913bd8f8332367","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-2.0.1.tgz","fileCount":10,"integrity":"sha512-5gEAxKNhJYgjjCo6TXPW76qeS2+mg+cHtH03o7ooNBOiDjxuVwzE4aWByo0uOwSzMB2He7wRB4TG2zCEuG9Djw==","signatures":[{"sig":"MEUCIDc6QK9lXTw8H6fxsmAifFt9pleuTp1KGVWRaaHOdyalAiEAuTAOhPundcgpJcPOhxNiSn/tARQbhdv7jKclD9Xu5lc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50385},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","@code-fixer-23/source":"./src/index.ts"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"26.0.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.0","vitest":"^4.1.4","vite-plugin-dts":"^4.5.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_2.0.1_1779994356858_0.7165181034029582","host":"s3://npm-registry-packages-npm-production"}},"2.0.2":{"name":"@code-fixer-23/pi-form-components","version":"2.0.2","license":"MIT","_id":"@code-fixer-23/pi-form-components@2.0.2","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"7257a42bfcdd85764d73d86676f95418ed8addb6","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-2.0.2.tgz","fileCount":3,"integrity":"sha512-x/3Dmyuyu9fCAU6paCvy38IAN717+S4cyS/XY4W61x4+nCnD1TCet/Cp3tS+X+AS3Qh96qbPCOSAnra0IKD2lw==","signatures":[{"sig":"MEUCIQCTioI5FF+lpMxdfUX0/7bJCEATEanSudX/NDvZ1Gs8WAIgNT2khwICqve3A2IWFRySVUjfTc4H6oVI+tSfBOExwIs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12834},"main":"./index.js","type":"module","types":"./index.d.ts","module":"./index.js","exports":{".":{"types":"./index.d.ts","import":"./index.js","default":"./index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"22.19.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^8.0.0","vitest":"^4.1.4","vite-plugin-dts":"^4.5.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_2.0.2_1781036668918_0.06956770979258153","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"@code-fixer-23/pi-form-components","version":"3.0.0","license":"MIT","_id":"@code-fixer-23/pi-form-components@3.0.0","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"3503a81744facdc1176ce61d2fa45457e087a1a4","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-3.0.0.tgz","fileCount":4,"integrity":"sha512-XGRFk/M7ZUlNKOaHP7wtvrgvVVxv9oX5Jg/o8tdkNd+ABTWjH2WUiPeVf8SeXotB0/iXHM+oxILW+yMUIx5b+g==","signatures":[{"sig":"MEYCIQD+1xwqo2k6C8+z58Bl1Z/i2FfUw/QWFrMFitGENkznMwIhAJpXo9XakFBL4opxJQPX7MhkoMaiSLYgTMu2uo00JI+o","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12521},"main":"./src/index.ts","type":"module","types":"./src/index.d.ts","module":"./src/index.ts","exports":{".":{"types":"./src/index.ts","import":"./src/index.ts","default":"./src/index.ts"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"22.19.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_3.0.0_1781111876337_0.2783336894925965","host":"s3://npm-registry-packages-npm-production"}},"3.0.1":{"name":"@code-fixer-23/pi-form-components","version":"3.0.1","license":"MIT","_id":"@code-fixer-23/pi-form-components@3.0.1","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"7bd1257cf1ecebbefec64eae6969146c32510ac4","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-3.0.1.tgz","fileCount":10,"integrity":"sha512-h0DX6KtGR7EyiALac6vkRHN3Qy5nSWXbutERy6aTthlXHZ5R2WIF6IxUeSf2frAjhih9DtyxLCh+LzCoSIqVzg==","signatures":[{"sig":"MEUCIQCUdJyrgwfbuUrC1VhETP8Iz5S85/pb94StsfjsppBBsgIgXG9sEhaIUVc9f30lNt1vXtHj20bskLoRG14K73bOpvA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30312},"main":"./index.js","type":"module","types":"./src/index.d.ts","module":"./index.js","exports":{".":{"types":"./src/index.d.ts","import":"./index.js","default":"./index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"22.19.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_3.0.1_1781226925256_0.38237243815714117","host":"s3://npm-registry-packages-npm-production"}},"3.1.0":{"name":"@code-fixer-23/pi-form-components","version":"3.1.0","license":"MIT","_id":"@code-fixer-23/pi-form-components@3.1.0","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"3daebb2d137b76b36612ab743fffcb975c3246e3","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-3.1.0.tgz","fileCount":10,"integrity":"sha512-o8Lfrxyp1YQnzITbT94qOxTeleq+t8yG7g2aDXCqB4oWICK6YCh/0n7tGui7++xe4dJbKAxbWu8VJXWaFyyHHQ==","signatures":[{"sig":"MEUCIEx/K6427qTvOQ9KgZmzVq+PP8Q5vzy04u/EfAqCqYQ/AiEAvQjsMrcwF0e+OMtUNtE7zkGkYWRCVyhcg9wdgBgUIkQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30312},"main":"./index.js","type":"module","types":"./src/index.d.ts","module":"./index.js","exports":{".":{"types":"./src/index.d.ts","import":"./index.js","default":"./index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"22.19.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_3.1.0_1781492357520_0.9421113468444602","host":"s3://npm-registry-packages-npm-production"}},"3.1.1":{"name":"@code-fixer-23/pi-form-components","version":"3.1.1","license":"MIT","_id":"@code-fixer-23/pi-form-components@3.1.1","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"5e7099bb39f1cae95946228fa791143aca5179f6","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-3.1.1.tgz","fileCount":4,"integrity":"sha512-Pt4O51aRZAVBnxXKg2LwxCm1yv+ka48OWPXMdl1+9WDDEBVZ8sHqF836eapI6H9IPMWgkZSprqx8iZQAoq7gOQ==","signatures":[{"sig":"MEYCIQD86kSYBMHtY/xaesB2G5zYGJQ3C3or9VJ631f5UNvXOAIhAI1xwJMCQP1whC5SVRI0k637DU6OsmV2GLrhDXZo5tkb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18394},"main":"./src/index.ts","type":"module","types":"./src/index.d.ts","module":"./src/index.ts","exports":{".":{"types":"./src/index.ts","import":"./src/index.ts","default":"./src/index.ts"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"22.19.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_3.1.1_1781640424177_0.8853377359996515","host":"s3://npm-registry-packages-npm-production"}},"3.1.2":{"name":"@code-fixer-23/pi-form-components","version":"3.1.2","license":"MIT","_id":"@code-fixer-23/pi-form-components@3.1.2","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"33e42a85dfcef45991e5edb316d394981193c9b9","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-3.1.2.tgz","fileCount":10,"integrity":"sha512-uxZ/9XxExPb0T/4p3Rj1qeclSOfg/jb92EbZQau1rpw03F1tX98hpupuABZqP1Enx/nUtaNlKdK1H2faihLy0w==","signatures":[{"sig":"MEUCIQC+lOcyHtLKbyVv6yhir75ZGSRk+XjtjMlGvjNxbn+76gIgBvTp2qBQYmqooHXyc/yMYZbKX/bIQJ9fHpaStCJ8EvU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30312},"main":"./index.js","type":"module","types":"./src/index.d.ts","module":"./index.js","exports":{".":{"types":"./src/index.d.ts","import":"./index.js","default":"./index.js"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"22.19.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_3.1.2_1781646415025_0.8217931854637748","host":"s3://npm-registry-packages-npm-production"}},"3.1.3":{"name":"@code-fixer-23/pi-form-components","version":"3.1.3","license":"MIT","_id":"@code-fixer-23/pi-form-components@3.1.3","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"78cfacb7cefaeecec240ed9825376d4f7ef839a4","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-3.1.3.tgz","fileCount":4,"integrity":"sha512-9EzOFLc7NkG7P08KtqUHXvm54h+LtM8I9uGmSfnOg9tdbOXmM6QTgdSYuINUZ7seMnBFgh5TZUdBsO3ktYQzIw==","signatures":[{"sig":"MEUCIQCTqhDFlJb1EPXFn2jJAv6jaSaOf4I2w8bPB8mY32NUmQIgMaVeO+tQuy2fNPCFsG+f2hIWlIrz5sVYhYY6tluCkBU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17693},"main":"./src/index.ts","type":"module","types":"./src/index.d.ts","module":"./src/index.ts","exports":{".":{"types":"./src/index.ts","import":"./src/index.ts","default":"./src/index.ts"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"22.19.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_3.1.3_1781656007424_0.8524868556456813","host":"s3://npm-registry-packages-npm-production"}},"3.1.4":{"name":"@code-fixer-23/pi-form-components","version":"3.1.4","license":"MIT","_id":"@code-fixer-23/pi-form-components@3.1.4","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"80b36d28ad16ed6fa19ec0201df06e8028c79e50","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-3.1.4.tgz","fileCount":4,"integrity":"sha512-A5ONpAcPV4YunTBXYPzuf2/VBvFMYYRPWZOXeVv63xQANu0gajg/qF+ak4UMO2T9V2Ho/oPJbqG8pA+h0Sz2Nw==","signatures":[{"sig":"MEYCIQCTBu5zkNajlt51krPuFIV4QYuE5U3Pqblx/i6fB3sG2QIhAJPRgaeannl6xd0+8uG6JbmG1Eo5RBfdiTelx3GAwfav","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17690},"main":"./src/index.ts","type":"module","types":"./src/index.d.ts","module":"./src/index.ts","exports":{".":{"types":"./src/index.ts","import":"./src/index.ts","default":"./src/index.ts"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"22.19.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_3.1.4_1781656952308_0.4153467681253469","host":"s3://npm-registry-packages-npm-production"}},"3.1.5":{"name":"@code-fixer-23/pi-form-components","version":"3.1.5","license":"MIT","_id":"@code-fixer-23/pi-form-components@3.1.5","maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"homepage":"https://github.com/louiss0/pi-packages","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"dist":{"shasum":"36a0a5c8da350472e420d12bf25d85f585252556","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-3.1.5.tgz","fileCount":5,"integrity":"sha512-9BOO9cXA0Ckrf24yDmkyIKl1+nafz8XWiLmeg3CZag6dY0Lxe2XMEZ0EDUN5ad2xxi+4L4M40th/OcCd+gmMLw==","signatures":[{"sig":"MEUCIALVGUuWmbY4OkUvilqvHMZS74BziRfv6bS9HEFGBA0TAiEA6ktNVDPq+ymY6caiaSVnhwzXIIohI+J67Rp7sRUqdMw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44917},"main":"./src/index.ts","type":"module","types":"./src/index.d.ts","module":"./src/index.ts","exports":{".":{"types":"./src/index.d.ts","import":"./src/index.ts","default":"./src/index.ts"},"./package.json":"./package.json"},"private":false,"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"repository":{"url":"https://github.com/louiss0/pi-packages","type":"git","directory":"pi-form-components"},"directories":{},"_nodeVersion":"22.19.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.4"},"peerDependencies":{"@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-form-components_3.1.5_1781658297559_0.05525424027575365","host":"s3://npm-registry-packages-npm-production"}},"3.1.6":{"name":"@code-fixer-23/pi-form-components","version":"3.1.6","private":false,"repository":{"type":"git","url":"https://github.com/louiss0/pi-packages","directory":"pi-form-components"},"homepage":"https://github.com/louiss0/pi-packages","license":"MIT","bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"publishConfig":{"access":"public"},"type":"module","main":"./src/index.ts","module":"./src/index.ts","exports":{"./package.json":"./package.json",".":{"import":"./src/index.ts","default":"./src/index.ts"}},"dependencies":{"tslib":"^2.3.0"},"peerDependencies":{"@earendil-works/pi-coding-agent":"*","@earendil-works/pi-tui":"*"},"devDependencies":{"vitest":"^4.1.4"},"_nodeVersion":"26.7.0","_id":"@code-fixer-23/pi-form-components@3.1.6","dist":{"integrity":"sha512-acz181pOy7rUu7Mm/TCad2z3dNRX2Ewd/HrXh1M2JOtvGbKJ2C2lxt0X3ubw8LyvRT+6tPV7DOS9iBdzU7zGlg==","shasum":"0644490f835cecb1e1e75260d4b469cfdd4f20f1","tarball":"https://registry.npmjs.org/@code-fixer-23/pi-form-components/-/pi-form-components-3.1.6.tgz","fileCount":5,"unpackedSize":43935,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEdKl7ccJTwSAyixBrJz2Y7FimBeUlnhPYa0Odyi/tQ9AiBsPFwjfriPN0CKGFR+RHUE9UvFHowaxfO2umByyseTvg=="}]},"_npmUser":{"name":"codebreaker10","email":"louisshelton0@gmail.com"},"directories":{},"maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-form-components_3.1.6_1787607447035_0.12869486008508346"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-25T17:24:22.715Z","modified":"2026-08-24T21:37:27.353Z","2.0.0":"2026-05-25T17:24:23.036Z","2.0.1":"2026-05-28T18:52:36.993Z","2.0.2":"2026-06-09T20:24:29.071Z","3.0.0":"2026-06-10T17:17:56.466Z","3.0.1":"2026-06-12T01:15:25.428Z","3.1.0":"2026-06-15T02:59:17.659Z","3.1.1":"2026-06-16T20:07:04.305Z","3.1.2":"2026-06-16T21:46:55.177Z","3.1.3":"2026-06-17T00:26:47.568Z","3.1.4":"2026-06-17T00:42:32.426Z","3.1.5":"2026-06-17T01:04:57.705Z","3.1.6":"2026-08-24T21:37:27.183Z"},"bugs":{"url":"https://github.com/louiss0/pi-packages/issues"},"license":"MIT","homepage":"https://github.com/louiss0/pi-packages","repository":{"type":"git","url":"https://github.com/louiss0/pi-packages","directory":"pi-form-components"},"maintainers":[{"name":"codebreaker10","email":"louisshelton0@gmail.com"}],"readme":"# @code-fixer-23/pi-form-components\r\n\r\n`@code-fixer-23/pi-form-components` is a TypeScript library of reusable interactive components for building form-driven workflows inside Pi extensions. Extension authors commonly need text inputs, selection pickers, multi-item checkboxes, confirmation prompts, and structured submission logic—this package provides all of those as composable TUI components that integrate directly with Pi's rendering and keybinding system.\r\n\r\nThe package solves the problem of rebuilding form infrastructure from scratch in every extension. Instead of reimplementing focus cycling, validation state, inline error display, lazy list loading, or external editor integration yourself, you declare the fields you need, supply a `parse` function that validates the collected values, and hand everything to `Form`. The result is a consistent, keyboard-first input experience that returns either a validated object or a cancel signal to your extension handler. Because every field implements the same `FormComponent` interface, you can mix built-in and custom fields within the same form without changing the submission or validation logic.\r\n\r\n[![npm version](https://img.shields.io/npm/v/%40code-fixer-23%2Fpi-form-components)](https://www.npmjs.com/package/@code-fixer-23/pi-form-components)\r\n[![npm downloads](https://img.shields.io/npm/dm/%40code-fixer-23%2Fpi-form-components)](https://www.npmjs.com/package/@code-fixer-23/pi-form-components)\r\n[![license](https://img.shields.io/github/license/louiss0/pi-packages)](https://github.com/louiss0/pi-packages/blob/main/LICENSE)\r\n[![CI](https://github.com/louiss0/pi-packages/actions/workflows/ci.yml/badge.svg)](https://github.com/louiss0/pi-packages/actions/workflows/ci.yml)\r\n\r\n## Installation\r\n\r\n```sh\r\npnpm add @code-fixer-23/pi-form-components\r\n```\r\n\r\nThis package requires the following peer dependencies from the Pi runtime:\r\n\r\n- `@earendil-works/pi-coding-agent`\r\n- `@earendil-works/pi-tui`\r\n\r\n## Components\r\n\r\n```ts\r\nimport {\r\n  ConfirmationBox,\r\n  createExternalEditorFactory,\r\n  Form,\r\n  LabelledInput,\r\n  MultiSelect,\r\n  Picker,\r\n  validateType,\r\n} from \"@code-fixer-23/pi-form-components\";\r\n```\r\n\r\n### Form\r\n\r\n`Form` coordinates multi-step data entry across a set of fields. When the form becomes focused, it activates the first field and begins routing keystrokes to it. The user moves forward with `Enter` or `Tab`, backward with `Shift`+`Tab` or the up arrow, and can cancel at any time with `Esc`. The form renders a centered title above the fields and an optional footer below them, giving the screen a consistent, navigable structure.\r\n\r\nIllustration:\r\n\r\n```text\r\n              Create Package\r\n\r\n› name\r\nmy-plugin\r\n\r\n  [x] Publish immediately?\r\n\r\nEnter next/submit • Tab switch field • Esc cancel\r\n```\r\n\r\nSubmission runs a validation cycle. When the user submits from the last field, `parse` receives the field values collected by name. If `parse` returns errors, the form remains open and displays each error message beneath its owning field. As the user continues editing, the form revalidates on every keystroke and removes resolved errors immediately. Once `parse` returns `undefined`, the form calls `done` with the validated object. If the user cancels with `Esc`, `done` receives `null` instead.\r\n\r\nArguments:\r\n\r\n- `object:options` configures the full form flow\r\n  - `string:title` renders a centered heading\r\n  - `FormField[]:fields` defines the ordered interactive fields\r\n  - `function:parse` validates collected values and returns per-field error arrays, or `undefined` when valid\r\n  - `string:footer` adds inline guidance below the form (optional)\r\n  - `number:spacing` controls blank lines between sections (default: `2`)\r\n- `FormTui:tui` requests rerenders as focus, filtering, and validation change\r\n- `function:done` receives submitted values or `null` on cancel\r\n\r\nExample:\r\n\r\n```ts\r\nconst form = new Form(\r\n  {\r\n    title: \"Create Package\",\r\n    fields: [\r\n      new LabelledInput(\"name\", theme),\r\n      new ConfirmationBox(\"publishNow\", theme, \"Publish immediately?\"),\r\n    ],\r\n    parse(values) {\r\n      if (values.name === \"\") {\r\n        return { name: [\"Name is required\"] };\r\n      }\r\n      return undefined;\r\n    },\r\n    footer: \"Enter next/submit • Tab switch field • Esc cancel\",\r\n  },\r\n  tui,\r\n  (values) => {\r\n    if (values === null) return;\r\n    // continue with validated form values\r\n  },\r\n);\r\n```\r\n\r\n### LabelledInput\r\n\r\n`LabelledInput` renders a labeled text cursor, accepts typed input, and keeps validation messages directly beneath the field. The label prefix changes to `› ` when the field has focus, making the active field immediately visible in a multi-field form. This is the default field type for collecting short string values such as names, paths, or descriptions.\r\n\r\nArguments:\r\n\r\n- `string:name` becomes both the rendered label and the submitted object key\r\n- `FormTheme:theme` colors the active label prefix and validation output\r\n- `string:initialValue` pre-populates the input (optional, default: `\"\"`)\r\n\r\nIllustration:\r\n\r\n```text\r\n› packageName\r\npi-form-components\r\nName must be lowercase\r\n```\r\n\r\nExample:\r\n\r\n```ts\r\nconst packageName = new LabelledInput(\"packageName\", theme);\r\npackageName.setFocused(true);\r\npackageName.setError([\"Name must be lowercase\"]);\r\n```\r\n\r\n### ConfirmationBox\r\n\r\n`ConfirmationBox` renders a checkbox-style row that the user toggles with `Space`. It contributes a boolean value to the submitted object and is appropriate for yes/no checkpoints such as enabling optional steps or confirming a potentially destructive action.\r\n\r\nThe component exposes both `toggle()` and `confirm()`. `toggle()` flips the value on and off in response to `Space`. `confirm()` sets the value to `true` permanently and cannot be reversed—useful in flows where acceptance should be a one-time action rather than a toggleable state.\r\n\r\nArguments:\r\n\r\n- `string:name` becomes the submitted key and field identity\r\n- `FormTheme:theme` colors the checkbox and validation output\r\n- `string:message` renders the confirmation prompt beside the checkbox\r\n\r\nIllustration:\r\n\r\n```text\r\n> [x] Include starter prompts?\r\n```\r\n\r\nExample:\r\n\r\n```ts\r\nconst includePrompts = new ConfirmationBox(\r\n  \"includePrompts\",\r\n  theme,\r\n  \"Include starter prompts?\",\r\n);\r\n```\r\n\r\n### MultiSelect\r\n\r\n`MultiSelect` lets the user pick any number of items from a list before submitting. Each item is rendered with a choice indicator that reflects its current selection state. The user navigates with the arrow keys and toggles individual items with `Space`. When the user presses `Enter`, `done` is called with the selected values in the order they were toggled. `Esc` cancels the session.\r\n\r\nThe visual style of the choice indicator is controlled by `itemChoiceStyle`:\r\n\r\n| Style | Unselected | Selected |\r\n|-------|-----------|----------|\r\n| `checkbox` (default) | `[ ]` | `[x]` |\r\n| `radio` | `( )` | `(*)` |\r\n| `dot` | `○` | `●` |\r\n| `diamond` | `◇` | `◆` |\r\n\r\nArguments:\r\n\r\n- `string:name` becomes the field label and the key in the submitted object\r\n- `object:config` configures the item list and appearance\r\n  - `SelectItem[]:items` defines selectable entries with `value`, `label`, and optional `description`\r\n  - `string:title` renders an optional heading (defaults to `name`)\r\n  - `number:spacing` adds vertical space above the list (default: `1`)\r\n  - `ItemChoiceStyle:itemChoiceStyle` sets the indicator style (default: `\"checkbox\"`)\r\n  - `object:styles` customizes per-role theme colors for the title and item rows\r\n- `TUI:tui` requests rerenders on navigation and toggle\r\n- `Theme:theme` applies Pi theme colors\r\n- `function:done` receives an array of selected values, or `null` on cancel\r\n\r\nWhen `MultiSelect` is used as a field inside a `Form`, its `value` getter returns the selected values as a comma-separated string so the submission object stays flat. When used standalone, the `done` callback receives the typed array directly.\r\n\r\nIllustration:\r\n\r\n```text\r\n› toppings\r\nWhat toppings do you want?\r\n\r\n[x] Cheese\r\n[ ] Pepperoni\r\n[x] Mushrooms     Earthy\r\n```\r\n\r\nExample:\r\n\r\n```ts\r\nconst toppings = new MultiSelect(\r\n  \"toppings\",\r\n  {\r\n    title: \"What toppings do you want?\",\r\n    itemChoiceStyle: \"checkbox\",\r\n    items: [\r\n      { value: \"cheese\", label: \"Cheese\" },\r\n      { value: \"pepperoni\", label: \"Pepperoni\" },\r\n      { value: \"mushrooms\", label: \"Mushrooms\", description: \"Earthy\" },\r\n    ],\r\n  },\r\n  tui,\r\n  theme,\r\n  (values) => {\r\n    if (values === null) return;\r\n    // values: string[]\r\n  },\r\n);\r\n```\r\n\r\n### Picker\r\n\r\n`Picker` is a searchable single-selection workflow for large command or option lists. It opens with a bordered list and a filter line. As the user types, the picker narrows results across the entire item set—not only what is currently visible. Navigation stays keyboard-driven throughout: arrow keys move the highlight, typing filters in real time, `Enter` finalizes the selection, and `Esc` cancels.\r\n\r\nTo avoid rendering a large list up front, `Picker` loads items in a lazy window. The initial view shows `itemLimit` items. As the user scrolls toward the bottom, the window expands by `lazyLoadStep` until the full set is visible. Typing a filter bypasses the lazy window and searches all items immediately.\r\n\r\nArguments:\r\n\r\n- `string:name` becomes the picker field identity and label\r\n- `object:config` defines picker behavior\r\n  - `string[]:items` provides the full set of selectable values\r\n  - `number:itemLimit` sets the initial visible list size\r\n  - `string:title` renders the picker heading (defaults to `name`)\r\n  - `string:helpText` overrides the footer guidance line\r\n  - `number:lazyLoadStep` controls how many items load when the window expands (default: `itemLimit`)\r\n  - `object:styles` customizes title, border, help text, and per-role item colors\r\n- `PickerTheme:theme` applies Pi theme colors\r\n- `FormTui:tui` requests rerenders after filtering and selection changes\r\n- `function:done` receives the selected string value, or `null` on cancel\r\n\r\nIllustration:\r\n\r\n```text\r\n┌──────────────────────────────┐\r\nCommands\r\nFilter: form\r\n› form.create            1\r\n  form.validate          2\r\n  form.preview           3\r\ntype to filter • ↑↓ navigate • enter execute • esc cancel\r\n└──────────────────────────────┘\r\n```\r\n\r\nExample:\r\n\r\n```ts\r\nconst picker = new Picker(\r\n  \"commands\",\r\n  {\r\n    title: \"Commands\",\r\n    items: [\"form.create\", \"form.validate\", \"form.preview\"],\r\n    itemLimit: 5,\r\n  },\r\n  theme,\r\n  tui,\r\n  (value) => {\r\n    if (value === null) return;\r\n    // continue with the chosen command\r\n  },\r\n);\r\n```\r\n\r\n### createExternalEditorFactory\r\n\r\n`createExternalEditorFactory` opens a file in an external editor such as VS Code or Helix from within a Pi extension. It returns a component factory that `ctx.ui.custom` accepts. When the factory runs, Pi suspends its own UI, opens the specified file in the configured editor, and displays a popup so the user knows the agent is waiting for the editor to close.\r\n\r\nThe edit session starts the moment the file opens. The factory reads the file's content before the editor launches and reads it again after the editor exits. `done` is called with `{ before, after, changed }` so the extension can decide whether to act on the result. If the editor command is invalid, spawning fails, or an I/O error occurs, `done` receives an `ExternalEditorError` instead.\r\n\r\nTo handle editors that return immediately without blocking (such as VS Code without `--wait`), the factory inspects the editor's `--help` output for a wait flag (`--wait` or `-w`) and appends it automatically when found and not already present in the command string.\r\n\r\nArguments:\r\n\r\n- `string:editorCommand` the editor binary and any extra flags (e.g. `\"code --reuse-window\"`, `\"hx\"`)\r\n- `string:filePath` the absolute path to the file to edit\r\n\r\nReturns a component factory compatible with `ctx.ui.custom`.\r\n\r\nIllustration:\r\n\r\n```text\r\n  Editing file: /path/to/config.md\r\n  Editor: code\r\n  Close the editor to return to Pi.\r\n```\r\n\r\nExample:\r\n\r\n```ts\r\nconst result = await ctx.ui.custom(\r\n  createExternalEditorFactory(process.env.EDITOR, \"/path/to/config.md\"),\r\n);\r\n\r\nif (result instanceof Error) {\r\n  ctx.ui.notify(result.message, \"error\");\r\n  return;\r\n}\r\n\r\nif (result.changed) {\r\n  // apply the updated content\r\n  console.log(result.after);\r\n}\r\n```\r\n\r\n## Building a custom field\r\n\r\nAny class that implements `FormComponent` can participate in a `Form` session alongside the built-in fields. The interface requires a `name` and `value` accessor plus three lifecycle methods:\r\n\r\n```ts\r\nexport interface FormComponent extends Component {\r\n  readonly name: string;\r\n  readonly value: string | number | boolean;\r\n  setFocused(focused: boolean): void;\r\n  setError(messages: string[]): void;\r\n  clearError(): void;\r\n  handleInput(data: string): void;\r\n}\r\n```\r\n\r\n`Form` calls `setFocused` when moving between fields so the active field can highlight itself. It calls `setError` and `clearError` during submission and live revalidation. Keystrokes that are not navigation keys are dispatched to the active field via `handleInput`. The `name` accessor identifies the field in the validated object; `value` is what gets included in the submission.\r\n\r\nExample of a minimal custom field:\r\n\r\n```ts\r\nimport { Container, Text } from \"@earendil-works/pi-tui\";\r\nimport type { FormComponent } from \"@code-fixer-23/pi-form-components\";\r\n\r\nclass RatingField extends Container implements FormComponent {\r\n  readonly name: string;\r\n  #rating = 3;\r\n  #errorText = new Text(\"\");\r\n  #labelText: Text;\r\n\r\n  constructor(name: string) {\r\n    super();\r\n    this.name = name;\r\n    this.#labelText = new Text(name);\r\n    this.addChild(this.#labelText);\r\n    this.addChild(this.#errorText);\r\n  }\r\n\r\n  get value() { return this.#rating; }\r\n\r\n  setFocused(focused: boolean) {\r\n    this.#labelText.setText(focused ? `› ${this.name}` : `  ${this.name}`);\r\n  }\r\n\r\n  setError(messages: string[]) { this.#errorText.setText(messages.join(\"\\n\")); }\r\n  clearError() { this.#errorText.setText(\"\"); }\r\n\r\n  handleInput(data: string) {\r\n    const digit = parseInt(data);\r\n    if (!isNaN(digit) && digit >= 1 && digit <= 5) this.#rating = digit;\r\n  }\r\n}\r\n```\r\n\r\n## Usage example\r\n\r\n```ts\r\nimport { ConfirmationBox, Form, LabelledInput } from \"@code-fixer-23/pi-form-components\";\r\n\r\nconst name = new LabelledInput(\"name\", theme);\r\nconst confirm = new ConfirmationBox(\"publishNow\", theme, \"Publish immediately?\");\r\n\r\nconst form = new Form(\r\n  {\r\n    title: \"Create package\",\r\n    fields: [name, confirm],\r\n    parse(values) {\r\n      if (values.name === \"\") {\r\n        return { name: [\"Name is required\"] };\r\n      }\r\n      return undefined;\r\n    },\r\n    footer: \"Enter next/submit • Space toggle • Esc cancel\",\r\n  },\r\n  tui,\r\n  (values) => {\r\n    if (values === null) return;\r\n    // continue the extension workflow with validated values\r\n  },\r\n);\r\n```\r\n\r\n## Development\r\n\r\nRun tasks from the workspace root with Nx:\r\n\r\n```sh\r\npnpm nx run pi-form-components:lint\r\npnpm nx run pi-form-components:typecheck\r\npnpm nx run pi-form-components:test\r\npnpm nx run pi-form-components:metadata\r\npnpm nx run pi-form-components:nx-release-publish\r\n```\r\n\r\nThe package is now published directly from `pi-form-components/` with no generated publish-output directory. `README.md` and the package source are used as-is during publishing.\r\n","readmeFilename":""}