{"_id":"@cogability/membership-kit","_rev":"18-cf7589cbf189f8b5dae0f0cc06d74bb6","name":"@cogability/membership-kit","dist-tags":{"latest":"0.9.1"},"versions":{"0.2.0":{"name":"@cogability/membership-kit","version":"0.2.0","_id":"@cogability/membership-kit@0.2.0","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"a8fd274b54ba0fe141cb79e087cd04664bd32611","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.2.0.tgz","fileCount":29,"integrity":"sha512-bT8FR2XIJa1SL+4SFzJVExNZPZkNztdNWvl4QF4t/jksPn7Ca/loYNYIpR0i063JgSLcmbNDNwnZvzGt0l1iTg==","signatures":[{"sig":"MEQCIHrY3U9Phv5QQAh4glrRdEJTO4DbRctwMcDXLJYJ3ZJAAiBy5O7TcG864zY7S/3yKHnFaM4bN3AoXSjcUyI7Fxf52A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":97680},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"c4291b9b1f91a09ea3ae054111ff3b1400ab41e1","scripts":{"audit:prod":"npm audit --production","prepublishOnly":"node scripts/check-secrets.js"},"_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.2.0_1776042880099_0.9756903799953602","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@cogability/membership-kit","version":"0.3.0","_id":"@cogability/membership-kit@0.3.0","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"a530d28f55f4f1f695bc6b6932685f6cc04c3528","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.3.0.tgz","fileCount":27,"integrity":"sha512-9nLexNVkVgj4DhdGzdRT1UyNyrHAW0SfstC2algUyEg+3DSfRPhvZibLLUBKpz+mwTJk/fAaT9xvqLF7df9Lzw==","signatures":[{"sig":"MEUCIQDKwzUach2leV0ntWIJr3LnI5nDXwwqnurlf6jn6PpEQwIgKTP+PytPh+OxazUoDoLgxyK6Uo+B7NoAX/1vmlKpEag=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88888},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"1f45c3814973e0abeb0047f51d4cfdbd537c48eb","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.3.0_1777258087429_0.3490644953532822","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@cogability/membership-kit","version":"0.3.1","_id":"@cogability/membership-kit@0.3.1","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"d99e3e44a2bbca2b3815751f0c53d0ffdbcb4e3f","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.3.1.tgz","fileCount":27,"integrity":"sha512-PfgbZBM9qTu/VliDVBpyN4lwBfWCbX4m9WMXJTb4aZQVKfePM1+GYGPo1Nr9D+djauxa6DfbMIg2SaQdlTA1Vw==","signatures":[{"sig":"MEYCIQDWbX8d9HENshKAgAf/DR7vd08Alis15Kw10pxyqgTPNQIhAPwxf56diCUG3yFR/IlvaYRqUfAUnz7BPF1KASpbJQbT","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90514},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"b6f1bfb74683e7ca754b553ead9311590c048637","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.3.1_1777293420314_0.2000997567713294","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@cogability/membership-kit","version":"0.3.2","_id":"@cogability/membership-kit@0.3.2","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"fa468cc2f9de95cf9cb2e849a2de2f54f7f642a4","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.3.2.tgz","fileCount":27,"integrity":"sha512-V+3EkcrdgSObMplFhVHm98xtJSBWNC7SNRnzopMaRwXJJbnuDk9+1XjJU3YetJhySZnDuJfbpAYBGkUEbUzz6Q==","signatures":[{"sig":"MEQCIHlLUWAls7f0OwTboFkv04wKFHbKyrB2EHnHCcI01vdLAiAYIuuhtb6Ki8ihyu/YYn3l3NqlCwggdAOab9IXUVp40w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90558},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"b6f1bfb74683e7ca754b553ead9311590c048637","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.3.2_1777294384396_0.7640756470666341","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@cogability/membership-kit","version":"0.4.0","_id":"@cogability/membership-kit@0.4.0","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"3e6fc039792dc525df93acbd7aa66816f640f0e9","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.4.0.tgz","fileCount":30,"integrity":"sha512-1QEUF0BPdpxRDD0fG7RCmizTBYCbjwE4pxkRPTzuBwRcxMjKGyxaDeWJskU/Ac80i4hTTdrOAs9Z/ywMQcUZSQ==","signatures":[{"sig":"MEUCIQD/+QCVN3s6Wuf2yoCJTH8xYlofsojkgJIAiZcKmG/K/wIgPicdSpG3hDRm0IlXIB6vFwlDhHLUr2k7gCJTKG8QdGw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":108159},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"5704bece694ba4150bb75a4cb580867946e858bf","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.4.0_1778815415531_0.18081225831713232","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@cogability/membership-kit","version":"0.4.1","_id":"@cogability/membership-kit@0.4.1","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"b22ea6ada47b837c92fd9afd5c839d0fe279ea82","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.4.1.tgz","fileCount":30,"integrity":"sha512-KWPzRKTQ/2RSlqTbCBmVCZy6lE40fo+RSPJKVO7GaRz+jACG+kr67JguLsKZObxN4wBWYOeeiLOfpCIzQkRvJQ==","signatures":[{"sig":"MEUCIH2pBVamKWqgKJbqUJybuoptyeBhnI7pVxr5mciXj7zxAiEA8Ds+JXPP5Ns69TMYtMjt5p+YMCgia2x2e9TjEypN8Cw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":108115},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"7840b7f5bb9615cce17739297de78fd7c6d416c0","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.4.1_1779751855318_0.9786626964833864","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@cogability/membership-kit","version":"0.5.1","_id":"@cogability/membership-kit@0.5.1","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"3edab429b31a8f619c0949729d364c303c864e35","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.5.1.tgz","fileCount":33,"integrity":"sha512-4R5nNSBYRUjEvgu2nkH1NhqoFGScIVNlbXvLi0gGrEYwiXFKBGihzRA7rL4GjdLRxMs2RwgDxnhWNDlBD+F0WA==","signatures":[{"sig":"MEUCIQDPruiT599ArhzPww/suea1CydKjK1TbtYZzQ62Wz+p3wIgSwCRA6douskq8DAeKt+oVXDwuC9UUK7RJOrYG+fm4bM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":121340},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"d2deb426f73aad604401fe43fcc14f8d366124d1","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.5.1_1779889799198_0.24503354781065245","host":"s3://npm-registry-packages-npm-production"}},"0.5.2":{"name":"@cogability/membership-kit","version":"0.5.2","_id":"@cogability/membership-kit@0.5.2","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"7714c4f0a294caad9e7af65f6481f58cf89498be","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.5.2.tgz","fileCount":33,"integrity":"sha512-v1dxqSzGQdj9nBrwEPlPQDxg6biidk7RF9kzU+OkTUnt9hrsRGuVcVxQqoWVo+SDhJd22ndZnStdi41ByhR1oA==","signatures":[{"sig":"MEUCIAH47xYXLAE6xQbErvR5rWuLWRtuOv3prDtXcycOkUTSAiEA9cpcx7Z+ZVa29pjiPBJW3kvi+PylLtWXJV41bOI0wKA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":128147},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"8aa458b6db90503bd6b91d3fffb3fb8c6ea26693","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.5.2_1780029113895_0.6484646221537658","host":"s3://npm-registry-packages-npm-production"}},"0.5.3":{"name":"@cogability/membership-kit","version":"0.5.3","_id":"@cogability/membership-kit@0.5.3","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"9b653f427de68c8013d63ec60e6533779420839b","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.5.3.tgz","fileCount":34,"integrity":"sha512-8v/LRPspDxwuQeAO0lbRS+ZRFy1besPulYHvOj1MGvueQa5TlUyaHE8AeunE9OlBQiCibUERZFpzPx9Xow/9Nw==","signatures":[{"sig":"MEUCIAs2ytbC28oZvUnpf8LuYgC2AcAqALtEY2gDQhcw/xgFAiEArnKv9BugURHWiPM64ghsjvlgW0TxXhnLU8dT2snO58c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":135508},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"1bae341ffdc55b4e2031ff10f9e258f08450a5b0","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.5.3_1781827790821_0.916362835745451","host":"s3://npm-registry-packages-npm-production"}},"0.5.4":{"name":"@cogability/membership-kit","version":"0.5.4","_id":"@cogability/membership-kit@0.5.4","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"907122580fb6eaa6c4c5711f5eb15f80ed383995","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.5.4.tgz","fileCount":34,"integrity":"sha512-J7Aj7YJnwDxn6Qur4x/DdJWR2mBY0B4gocxMxeaGsW2JiH+Ie1bJb9cmQ0hrzdex9yRPG7d42iRpmgleex1InA==","signatures":[{"sig":"MEUCICxCUhp4b1XiY4xeNMHD06NB3/RK5bomJhvQvSTKJyERAiEA8E+lJsISmjEvtzJskkxcDAU/hK9TiBEiSPpghdhhm1w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":142639},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"da9cb6596914892ab2377c99102c6cd12183e47d","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.5.4_1781924145634_0.3774831874765405","host":"s3://npm-registry-packages-npm-production"}},"0.5.5":{"name":"@cogability/membership-kit","version":"0.5.5","_id":"@cogability/membership-kit@0.5.5","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"01616be54c232c6e03869be8e8d39c28e18b918e","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.5.5.tgz","fileCount":34,"integrity":"sha512-+M0NiGs++1TY1bPBraSrgorLkeoiVDjcy2WMSskT4IGVjsGxPBHcIvM1zAGfui3JAaxsL3vUfThWHlVFh6/hxg==","signatures":[{"sig":"MEQCIH7GRA4cYlk6rbD/cFit2wt5K1Hjg8Aq/XpiHDiyVoVEAiBxY1JjWrOffsc235O88xIzdXmfgniAtQxBk8Mu/VsE1A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":143037},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"cbe64f210781f4e4d28d316ca775219ff80e73f3","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.5.5_1781925672591_0.7891645420564677","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@cogability/membership-kit","version":"0.6.0","_id":"@cogability/membership-kit@0.6.0","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"7a680aaab1e098e8d5d757d81de9cb4ae770a585","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.6.0.tgz","fileCount":34,"integrity":"sha512-oBpZs9GnZLRtNHZdp48iV4de5SFnHLMD7HmRtgbDPpVC7EMspQTmFJXrvkw3taO4ph2LQ25U3R8BPCkzER1dFw==","signatures":[{"sig":"MEUCIQCswSAEe/1HMZtKzH5SpabKfI5mskRFkcYqMAOngqmhzAIgOoXL0E8KqRri/uDQPS24PMP+nrz+PQKwHIXjxZtcHXY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":146218},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"9a85fad36fd371ffff63bf72f525325e3c683e64","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"11.5.1","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"24.5.0","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.6.0_1783132172706_0.39236084178274333","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@cogability/membership-kit","version":"0.6.1","_id":"@cogability/membership-kit@0.6.1","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"4353dd8dcc278615a820860c4f5dd12b3e37ebd6","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.6.1.tgz","fileCount":34,"integrity":"sha512-7mpCwmcjs3GzHyQH1XT441Fo1JxurWjqGef00SsRK0+GPFND1MOvyEUC3NYpgJMXtoNY8878K7FXja46s9anPQ==","signatures":[{"sig":"MEQCIDgUYMOFYV0wIDFCSxOL0upIZPrn9sURkbbIe4OyYdv1AiBude8f8UX/EqxXGLiutVbo8TN/lpKL4F6ZeNN0YySZNg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":146640},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"585217722bd7d62cc688c9b04626062550334966","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"10.8.2","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"20.20.2","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.6.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.6.1_1785639464759_0.7133661202155162","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@cogability/membership-kit","version":"0.7.0","_id":"@cogability/membership-kit@0.7.0","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"9c4eaacebe428eec585dd494bf6d11bb9ee784ee","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.7.0.tgz","fileCount":35,"integrity":"sha512-NzgHPxG1uQnlZfsEILhKJPgBQcas40HFW2kI60b0zDlcxEN1HOmFAIlFjOcaLsOVWqexskBTNC5gRUpcfUrnRQ==","signatures":[{"sig":"MEUCIQCKZLrg0k5TOY+FLO0hf81kWkgTRcmE8L1x/dkmRtXqyAIgAhmEIQapgxKLgHfv5zBoTtwW+GRXcPPj2pGY3bFAql0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":150856},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"6d84b3a2100aa243635b357d0f85f331ef584661","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"10.8.2","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"20.20.2","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.7.0_1785643004301_0.005511777094040493","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@cogability/membership-kit","version":"0.7.1","_id":"@cogability/membership-kit@0.7.1","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"6a323ac1b1015699db9e6a607ef83b4ad29f0eb3","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.7.1.tgz","fileCount":35,"integrity":"sha512-sz//jB81zFRv1ftYDyc9XhiO7EDv60H7HavIC7PMSratQImZQwzc7G3PXDI34E8roZNP+JnrUBZ642Lm/ttDyw==","signatures":[{"sig":"MEQCICQM/mflXZBMd8+l2KYk5nzzBLpCLTSdTTewbJwCZQicAiAlQGh3q3ygvrOO+ea9tjdPEHyu08gCLPAe4tD6JQLb5g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":150856},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"78b02810624226d717a4e03dda158f33e250d020","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"10.8.2","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"20.20.2","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.8.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.7.1_1785990467710_0.5091584521729517","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@cogability/membership-kit","version":"0.8.0","_id":"@cogability/membership-kit@0.8.0","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"d4fc91abc3aa29b321b46b2b3011c2adb9c51a7c","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.8.0.tgz","fileCount":35,"integrity":"sha512-FIS7/Ty1gTAxbM+YGJhaxE76WBbHGZpn4Hm4f/FrQpyiJ4ruq0qBe6s9KR9ax7Bp9Yqatqq5L6sjmZzFAJwB6w==","signatures":[{"sig":"MEUCIQClkcReWeBZzIafUU3M2WyFCB9byn4LHzguxObz5QyC4QIgSnEADIctrtvRhStKjUz9ydrY1/kwHb/xIlfAZwU/CrU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":151839},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"ee72cb7a7ba566611fd8ef303ae26f1cfb2e6063","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"10.8.2","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"20.20.2","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.8.0_1786056222773_0.5324881262409809","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@cogability/membership-kit","version":"0.9.0","_id":"@cogability/membership-kit@0.9.0","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"dist":{"shasum":"d937d4a7b0d4c0384a5eebd6d01ec3190e6a939b","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.9.0.tgz","fileCount":37,"integrity":"sha512-WN2NG4Il/uQZwA1Nr17Fk4gLZWhaxDKrY3KYDIgMSgVeBr8ThH5O4XcS5wOKaTcYvrqDgBlJESv+a6gZk5yMgg==","signatures":[{"sig":"MEYCIQCtfwms6JhM1PVFQ6lguLRPufU9+EDeVoj8HPiUA/fUpAIhAPH/TwtuUCJ93hlIE8myM3ts0b4z8xiloirFarn7FtNU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":174332},"main":"./src/index.js","type":"module","exports":{".":"./src/index.js"},"gitHead":"f70a84d97bae80582d80461372455506a2a395c1","_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"_npmVersion":"10.8.2","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","directories":{},"_nodeVersion":"20.20.2","dependencies":{"oidc-client-ts":"^3.5.0","@cogability/sdk":"^0.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/membership-kit_0.9.0_1786070516984_0.9329254739501072","host":"s3://npm-registry-packages-npm-production"}},"0.9.1":{"name":"@cogability/membership-kit","version":"0.9.1","type":"module","exports":{".":"./src/index.js"},"main":"./src/index.js","publishConfig":{"access":"public"},"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","react-router-dom":"^7.0.0"},"dependencies":{"@cogability/sdk":"^0.9.0","oidc-client-ts":"^3.5.0"},"_id":"@cogability/membership-kit@0.9.1","gitHead":"fd59b6a92da3ba7dcefcb68303bd9ef851306f7e","description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-mnU8CS1iwXMlHcIWuMiM2A+0qIfy8F6cREa2/7C4+c022tekdotCEulh3UZ/2fgTQphX4tVS71h72huMcS63dg==","shasum":"737cf5a4dc35337e5da2552ce3ad1bb8603b6a3b","tarball":"https://registry.npmjs.org/@cogability/membership-kit/-/membership-kit-0.9.1.tgz","fileCount":38,"unpackedSize":181444,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCuma6b5XDc/l6UenGnF6xsJZEE6d30tKFSaO8nHnwV1gIhAIo6SCcxGPKnb6EfhcexEu+ZmkOma94q8eUNwfCYM7N3"}]},"_npmUser":{"name":"jimhoskins","email":"jimh@cogability.com"},"directories":{},"maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/membership-kit_0.9.1_1786107819413_0.8206353442152354"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-13T01:14:39.984Z","modified":"2026-08-07T13:03:39.734Z","0.2.0":"2026-04-13T01:14:40.231Z","0.3.0":"2026-04-27T02:48:07.563Z","0.3.1":"2026-04-27T12:37:00.513Z","0.3.2":"2026-04-27T12:53:04.608Z","0.4.0":"2026-05-15T03:23:35.669Z","0.4.1":"2026-05-25T23:30:55.497Z","0.5.1":"2026-05-27T13:49:59.422Z","0.5.2":"2026-05-29T04:31:54.036Z","0.5.3":"2026-06-19T00:09:50.978Z","0.5.4":"2026-06-20T02:55:45.766Z","0.5.5":"2026-06-20T03:21:12.775Z","0.6.0":"2026-07-04T02:29:32.856Z","0.6.1":"2026-08-02T02:57:44.907Z","0.7.0":"2026-08-02T03:56:44.450Z","0.7.1":"2026-08-06T04:27:47.868Z","0.8.0":"2026-08-06T22:43:42.931Z","0.9.0":"2026-08-07T02:41:57.156Z","0.9.1":"2026-08-07T13:03:39.555Z"},"description":"React 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).","maintainers":[{"name":"jimhoskins","email":"jimh@cogability.com"}],"readme":"# @cogability/membership-kit\n\nReact 19 components, hooks, pages, and an `AuthProvider` for building a CogAbility-powered membership site. Built on top of [`@cogability/sdk`](https://www.npmjs.com/package/@cogability/sdk).\n\nThe kit ships a complete, production-ready membership SPA: anonymous chat on a public landing page, App ID sign-in, member onboarding wizard, profile management, and an authenticated members page with streaming chat. Clone the [cogbot-membership-website-template](https://github.com/CogAbility/cogbot-membership-website-template) to get started with zero configuration.\n\n## Installation\n\n```bash\nnpm install @cogability/membership-kit\n```\n\nPeer dependencies (install alongside the kit):\n\n```bash\nnpm install react react-dom react-router-dom oidc-client-ts\n```\n\n---\n\n## `useBuddyChat` hook\n\nManages the complete chat lifecycle — session init, greeting, streaming, and conversation history.\n\n```jsx\nimport { useBuddyChat } from '@cogability/membership-kit';\n\nfunction MyChat() {\n  const {\n    messages,          // { id, role: 'user'|'assistant', content }[]\n    isLoading,         // true while a message response is in flight\n    isInitializing,    // true during session init + greeting fetch\n    error,             // string | null\n    streamingText,     // in-progress assistant text during SSE streaming\n    sendMessage,       // (text: string) => void\n    retry,             // () => void — starts a new chat (rotates chat_id)\n    fetchConversationHistory, // () => Promise<ConversationHistoryResponse>\n    // Anonymous turn limit (null for authenticated users or when no limit is configured)\n    turnsPerDay,       // number | null — configured daily limit from Cloudant\n    remaining,         // number | null — turns remaining today (server-authoritative)\n    limitReached,      // boolean — true once the daily limit is hit\n  } = useBuddyChat();\n\n  return (\n    <div>\n      {messages.map(msg => (\n        <p key={msg.id}><strong>{msg.role}:</strong> {msg.content}</p>\n      ))}\n      {streamingText && <p><strong>assistant:</strong> {streamingText}</p>}\n    </div>\n  );\n}\n```\n\n### Anonymous turn limit\n\nWhen the cogbot has `anonymous_limits.turns_per_day` configured in its Cloudant config document, `useBuddyChat` exposes the limit state for anonymous users:\n\n| Field | Type | Description |\n|---|---|---|\n| `turnsPerDay` | `number \\| null` | The configured daily limit. `null` for authenticated users or when no limit is set. |\n| `remaining` | `number \\| null` | Turns remaining today. Accurate from the first render — seeded from the server on init. |\n| `limitReached` | `boolean` | `true` once the server returns a 429 `anon_turn_limit` response. Persisted across page refreshes. |\n\n`sendMessage` is a no-op while `limitReached` is `true`. Once the limit is hit, `BuddyChat` replaces the input area with the site-configured `limitReachedHeading` / `limitReachedBody` / `limitReachedCtaLabel` copy from `site.config.js`.\n\n**Counter accuracy:** `remaining` is seeded from the real server-side count on every page load (init endpoint) and persisted to `localStorage` keyed by cogbot ID and UTC date. It resets automatically at UTC midnight, consistent with the server. This means:\n- Refreshing the page shows the correct remaining count, not a reset \"10 of 10\".\n- Opening an incognito window shows the correct remaining count.\n- Multiple devices on the same IP share the same server-side bucket.\n\n### `retry()` — New Chat\n\nCalling `retry()` starts a brand-new conversation:\n\n1. Calls `cam.rotateChatId()` — mints a fresh `chat_id` UUID so PFC2 opens a new LangGraph RAG checkpoint on the next message turn. The previous conversation history is preserved server-side but is no longer reachable from this session.\n2. Clears `messages` and `error`.\n3. Re-runs the full init sequence (`initAnonymous`/`initAuthenticated` → `initCogbot` → `fetchGreeting`).\n\n```jsx\n<button onClick={retry}>New Chat</button>\n```\n\n### `fetchConversationHistory()` — View Transcript\n\nReturns the DI + RAG conversation thread for the current `chat_id` from PFC2's native history endpoint. SDI turns are excluded (SDI manages its own short-term context window independently).\n\n```jsx\nconst history = await fetchConversationHistory();\n\n// history.turns:\n// [{ role: 'user', content: '...' }, { role: 'assistant', content: '...' }]\n\n// history.transcript_text:\n// \"User: ...\\nAssistant: ...\"\n\n// history.summary (string | null):\n// Set when SummarizationMiddleware has condensed older exchanges.\n```\n\n---\n\n## `BuddyChat` component\n\nA fully-styled chat widget backed by `useBuddyChat`. Drop it into any page:\n\n```jsx\nimport { BuddyChat } from '@cogability/membership-kit';\n\n<BuddyChat\n  height=\"600px\"           // optional — fixes the panel height\n  className=\"\"             // optional — extra Tailwind/CSS classes\n  hideHeader={false}       // optional — hide the header bar (bot name + icons)\n/>\n```\n\n| Prop | Type | Default | Description |\n|---|---|---|---|\n| `height` | string | — | CSS height for the chat panel. Omit for full flex-grow behavior. |\n| `className` | string | `''` | Extra classes applied to the outermost `div`. |\n| `hideHeader` | boolean | `false` | Hide the header bar (useful when embedding inside a card that has its own header). |\n\nThe kit's `BuddyChat` includes a **New Chat** button in the header and a **View Transcript** panel in the footer. Both are available on every page that renders the component — including the public landing page (anonymous users) and the authenticated members page.\n\n---\n\n## How New Chat and View Transcript work end-to-end\n\n```\nUser clicks \"New Chat\"\n  ↓\nuseBuddyChat.retry()\n  ↓\ncam.rotateChatId()          ← new UUID stored as buddy_chat_id\n  ↓\ncam.initAnonymous/Authenticated()\ncam.initCogbot()\ncam.fetchGreeting()          ← fresh greeting from a new RAG thread\n  ↓\nUI: messages cleared, new greeting shown\n\nUser clicks \"View Transcript\"\n  ↓\nuseBuddyChat.fetchConversationHistory()\n  ↓\ncam.fetchConversationHistory()\n  ↓\nGET /api/cogbots/{id}/id/{uid}/conversation-history?chat_id=<current>\n  ↓\nPFC2 reads RAG LangGraph checkpoint at general_thread_id\n  ↓\nReturns { turns, transcript_text, summary? }\n  ↓\nUI: inline transcript panel rendered; summary block shown if present\n```\n\n---\n\n## AuthProvider and authentication\n\n```jsx\nimport { AuthProvider, useAuth } from '@cogability/membership-kit';\n\n// Wrap your app (already done in App.jsx)\n<AuthProvider config={siteConfig}>\n  <YourApp />\n</AuthProvider>\n\n// In any component\nconst { user, idToken, isLoading, login, logout, sessionExpiredReason } = useAuth();\n```\n\n### AuthProvider props\n\n| Prop | Default | Purpose |\n|---|---|---|\n| `persistSession` | `true` | Keeps the login in `localStorage` so it survives a tab close. Pass `false` for a session that ends with the tab. |\n| `idleTimeoutMinutes` | `30` (SDK default) | Forwarded to `AuthClient`. Signs the user out after this many minutes without activity in the tab. Pass `0` to disable. |\n| `absoluteCapHours` | `12` (SDK default) | Forwarded to `AuthClient`. Signs the user out this many hours after sign-in, regardless of activity. Pass `0` to disable. |\n\nPersisting the session matters more than it sounds: App ID issues no refresh\ntokens to SPA clients, so a tab-scoped login means members re-run the emailed\nmulti-factor code on essentially every visit. With the default, a returning\nmember lands signed in as long as they are still within the 30-minute idle\ntimeout and the 12-hour absolute cap described below — those two bounds are\nenforced client-side on top of persistence and apply even on the same\ndevice, so persisting the session avoids a *tab close* forcing a fresh login,\nbut it does not extend a session past either bound. Beyond that, a member is\nalso prompted again on a new device or after the tenant's SSO inactivity\nwindow lapses.\n\n```jsx\n// Opt out — session ends when the tab closes\n<AuthProvider persistSession={false}>\n  <YourApp />\n</AuthProvider>\n```\n\n```jsx\n// Override the session bounds for this deployment\n<AuthProvider idleTimeoutMinutes={15} absoluteCapHours={8}>\n  <YourApp />\n</AuthProvider>\n```\n\n#### Session bounds and `sessionExpiredReason`\n\n`AuthProvider` enforces two browser-side session limits — a 30-minute idle\ntimeout and a 12-hour absolute cap, matching what CAM and `fe-ctm` already\nenforce server-side (HIPAA 164.312(a)(2)(iii) automatic logoff, CJIS AC-12\nsession termination). Both are active by default; override them with the\n`idleTimeoutMinutes` / `absoluteCapHours` props above.\n\nWhile a user is signed in, `AuthProvider` runs the SDK's activity monitor so\nan idle tab is actually signed out, not just left showing stale content until\nthe next API call. When either bound is crossed, `AuthProvider`:\n\n- clears the `cam_token` / `cam_access_token` sessionStorage mirror that\n  `useBuddyChat` and `buddyApi` read directly, so the chat widget cannot keep\n  using a token from a session that has already ended;\n- resets `user`, `isMember`, `roles`, and the rest of the derived auth state,\n  the same as calling `logout()`;\n- sets `sessionExpiredReason` to `'idle'` or `'absolute'`.\n\n```jsx\nconst { sessionExpiredReason } = useAuth();\n\nif (sessionExpiredReason) {\n  // Distinguish \"you signed out\" from \"you were signed out\".\n  // e.g. show \"You were signed out after 30 minutes of inactivity.\"\n}\n```\n\n`sessionExpiredReason` is `null` until a bound is crossed, and is cleared\nautomatically on the next successful sign-in.\n\nThe anonymous chat session is stored the same way. It uses the SDK's\n`PersistentBrowserSessionStore`, so a visitor keeps one `uid` across tab closes\nrather than being issued a new one — which previously reset their anonymous\nturn allowance. Existing visitors are migrated automatically on first read.\n\n---\n\n## Access-code membership gate\n\nSome namespaces require an invite/access code before a logged-in user can become a member. `AuthProvider` handles the full redemption flow; `RoleGate` and `AccessCodeChallenge` surface it to the user automatically.\n\n**End-user experience:** the user logs in normally → `AuthProvider` calls `validateMembership` → if the namespace is code-gated, the member area shows a code-entry form instead of the chat → the user enters their code → on a valid code, membership is provisioned and the member area loads immediately, with no page reload required.\n\n### AuthProvider — access-code state\n\nAfter login, if `validateMembership` returns `codeRequired: true`, `AuthProvider` sets `membershipStatus` to `'code_required'` and exposes the following additional state via `useAuth()`:\n\n| Context value | Type | Description |\n|---|---|---|\n| `codeRequired` | boolean | `true` when the namespace requires a code and the user is not yet a member. |\n| `codeError` | string \\| null | Human-readable error message after a failed `redeemCode` attempt; `null` otherwise. A generic \"invalid or expired\" message on most HTTP 400s, CMG's specific message verbatim when the code belongs to a different cogbot (`wrong_product`), or a \"service temporarily unavailable\" message on a 503/network failure. |\n| `codeSubmitting` | boolean | `true` while a `redeemCode` call is in-flight. Useful for disabling the submit button and showing a spinner. |\n| `membershipStatus` | string | `'code_required'` when awaiting a code, plus the standard values `'none' \\| 'checking' \\| 'member' \\| 'not_member' \\| 'error'`. |\n\n### `redeemCode(code)` — context function\n\n```jsx\nconst { redeemCode, codeSubmitting, codeError } = useAuth();\n\nconst result = await redeemCode('ABC-123');\n// result: { success: boolean, geofenced: boolean, unavailable: boolean }\n```\n\n| Return field | Type | Description |\n|---|---|---|\n| `success` | boolean | `true` when the code was accepted and `isMember` is now `true`. |\n| `geofenced` | boolean | `true` when the user's IP was rejected by the geofence after code entry. |\n| `unavailable` | boolean | `true` when the redemption service returned 503 or a network error occurred. |\n\nOn success, `AuthProvider` automatically flips `isMember` to `true`, populates `roles`, and clears `codeRequired` — no further action needed. On failure, `codeError` is set and `codeRequired` remains `true` so the user can retry.\n\n### RoleGate — automatic code-challenge rendering\n\n`RoleGate` checks `codeRequired && !isMember` before the standard membership check. When that condition is true it renders `<AccessCodeChallenge />` instead of `<AccessDenied />`. Once `redeemCode` succeeds and `isMember` becomes `true`, the gate re-renders and passes through to its children — no routing change required.\n\n```jsx\nimport { RoleGate } from '@cogability/membership-kit';\n\n// Wrap any page that requires membership:\n<RoleGate>\n  <MembersPage />\n</RoleGate>\n\n// With an optional role check:\n<RoleGate requiredRole=\"bab:premium\">\n  <PremiumContent />\n</RoleGate>\n```\n\n| Prop | Type | Description |\n|---|---|---|\n| `requiredRole` | string | Optional. After membership is confirmed, also verify this role (e.g. `\"member\"` or `\"bab:premium\"`). |\n| `children` | ReactNode | Content to render when all checks pass. |\n\n**Render logic (in order):**\n\n1. Validating → spinner\n2. Geofenced → `<AccessDenied variant=\"geofenced\" />`\n3. `codeRequired && !isMember` → `<AccessCodeChallenge />`\n4. Not a member / validation error → `<AccessDenied />`\n5. `requiredRole` not held → `<AccessDenied />`\n6. All checks pass → `children`\n\n### `AccessCodeChallenge` component\n\nA self-contained code-entry card. Reads `codeRequired`, `codeError`, `codeSubmitting`, and `redeemCode` from `AuthContext`; returns `null` when `codeRequired` is `false`, making it safe to mount unconditionally.\n\n`RoleGate` renders this automatically — you only need to import it directly if you want to place the form somewhere other than the gate.\n\n```jsx\nimport { AccessCodeChallenge } from '@cogability/membership-kit';\n\n<AccessCodeChallenge\n  title=\"Enter your access code\"\n  description=\"This area is available to members with an access code.\"\n  placeholder=\"Access code\"\n  submitLabel=\"Submit\"\n  onSuccess={() => navigate('/members')}\n/>\n```\n\n| Prop | Type | Default | Description |\n|---|---|---|---|\n| `title` | string | `'Enter your access code'` | Card heading. |\n| `description` | string | `'This area is available to members with an access code. Enter yours below to continue.'` | Body copy beneath the heading. |\n| `placeholder` | string | `'Access code'` | Input placeholder and `aria-label`. |\n| `submitLabel` | string | `'Submit'` | Submit button label. |\n| `successMessage` | string | `'Access granted.'` | Screen-reader-only live-region text announced after successful redemption. |\n| `onSuccess` | function | — | Optional callback fired after `redeemCode` returns `success: true`. |\n\n### Required environment variables\n\n| Variable | Description |\n|---|---|\n| `VITE_CMG_URL` | Base URL of the CMG service (e.g. `https://cmg.example.com`). Defaults to `http://localhost:3010` in dev. |\n| `VITE_SITE_NAMESPACE` | Site/cogbot namespace (e.g. `bab`). Defaults to `'bab'` in dev. |\n\nBoth variables are read by `AuthProvider` at startup to construct the `CmgClient` instance. They must be set in your `.env` (or deployment environment) for the access-code flow to reach the correct CMG endpoint.\n\n> For a full picture of the access-code system — CMG backend routes, code provisioning, and admin tooling — see the cross-service hub doc: [`cac-coguniversity-access-codes/docs/access-code-membership.md`](../../cac-coguniversity-access-codes/docs/access-code-membership.md).\n\n---\n\n## Exported components and pages\n\n| Export | Description |\n|---|---|\n| `App` | Root application shell (router, auth, providers) |\n| `BuddyChat` | Standalone chat widget |\n| `CogBotEmbed` | Minimal embed wrapper for the chat widget |\n| `Header` / `Footer` | Site header and footer |\n| `Hero` | Public landing page hero section |\n| `Features` / `About` / `Testimonials` | Landing page sections |\n| `OnboardingProgressIndicator` | Step indicator for the onboarding wizard |\n| `LoginPage` | App ID login page |\n| `MembersPage` | Authenticated members page |\n| `OnboardingPage` | New-member onboarding wizard |\n| `ProfilePage` | Member profile management |\n| `CallbackPage` | OAuth callback handler |\n| `AccessDenied` | Non-member / role-denied screen |\n| `AccessCodeChallenge` | Access-code entry form (rendered by `RoleGate` automatically; see above) |\n| `AuthProvider` | OIDC auth context provider |\n| `ProtectedRoute` | Route guard (redirects to login if unauthenticated) |\n| `RoleGate` | Renders children only when membership/roles are satisfied |\n| `useBuddyChat` | Chat lifecycle hook (see above) |\n| `useAuth` | Auth state hook |\n| `useAuthorization` | Membership/role check hook |\n| `useSiteConfig` | Site config context hook |\n| `SiteConfigProvider` | Config context provider |\n| `cam` | The underlying `CamClient` instance (advanced use) |\n\n---\n\n## Source\n\nKit source lives in [`CogAbility/cogability-packages`](https://github.com/CogAbility/cogability-packages) under `packages/membership-kit/`. Contribute kit changes there — the template consumes the kit as a normal npm dependency.\n","readmeFilename":"README.md"}