{"_id":"@casys/mcp-view-components","_rev":"12-cc17c174097c03e264f4993966c74ae4","name":"@casys/mcp-view-components","dist-tags":{"latest":"0.9.0"},"versions":{"0.1.0":{"name":"@casys/mcp-view-components","version":"0.1.0","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.1.0","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"83aa2a316032904558394a483072eaf89e23047e","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.1.0.tgz","fileCount":71,"integrity":"sha512-OS6ta0ZEmOou7+nrrOAMwyUMUINAL+Sh3n+II9ebH80PoGAF6DLxp3Wmo/k/PawqhzcpSifY4U2nMfteG5tMJA==","signatures":[{"sig":"MEUCICS9EQMXAnERKMH/vM/o3TbfXY93Tj0Kk+7O1000Wf/1AiEA2Cz3ONBT8o+OPJF1fFIMHfHcpejGUouifEWXZDJInYI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":253261},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"dcde8fa3bd1a6ae135c816381aafb4d084635347","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.0","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.1.0_1788170960539_0.04585191677465894","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@casys/mcp-view-components","version":"0.2.0","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.2.0","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"32ed758a20ea944fc1953863269acaf030a2ea75","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.2.0.tgz","fileCount":71,"integrity":"sha512-s+oio2MJ2Ig/gB/o8o4wpAiSAmG+/BkTZysULhaWVLzgDDV6yevmiz1jTPNl8GbOCnFG+h/Khxl8HfVJDsRKBQ==","signatures":[{"sig":"MEUCIQDfq5e91vIbyZXsmh8+p6G7rN6wFqBQAdlFFOBcW54wvAIgEi3d/rHscVidh4H6K731A6Ci3nU9uNp0DUFmtSWiYN0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":274864},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"0629f67179868c9f17a3fb6705da32fdfcbcc216","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.1","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.2.0_1788176832792_0.39404199202664225","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@casys/mcp-view-components","version":"0.2.1","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.2.1","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"ecb5388ae153184cda2bc9fed1a5fe4b22b4e05c","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.2.1.tgz","fileCount":71,"integrity":"sha512-S0x+w+yscAWLysO7txcNkLBNTdGryK6o9pmitwc0ZIAtuwuHBwcinD49E7l7MYJVAfSLRPblZKl+bNF1AzvX+Q==","signatures":[{"sig":"MEQCID+HRYUpWVGw09N86Y0gnKP8JuQIU7kedp/IHXVosyW+AiAruEePWhI2LT43OPvh/fW5hWYXvPHcjHgHxkz1WS1D4g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":278507},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"31a44e64464975e0ccf675413e113789d1ab5f87","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.2","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.2.1_1788190473587_0.18771775758634446","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@casys/mcp-view-components","version":"0.3.0","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.3.0","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"f8cf37054f19e7916a6757ec7e881113778287a9","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.3.0.tgz","fileCount":71,"integrity":"sha512-CTDj0rO9YuxjsNZF9vlrxovkHGC10X+Fj2fQBzeIG9pixdxhNYFZJDlc+AUFU9/5vPWYtrrcMMB+c140C1bqIA==","signatures":[{"sig":"MEYCIQCOgMSM89bOz34GXKg7WzNmGlsSV2cm/L3nwMpBQwihXwIhAM+esziGijKPsfdWwnAPNF1fi1rFN/wFWHGaf6GOqJpU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":290010},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"e3c76438825ac8deaa05f85b0d218aa669a25bb0","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.2","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.3.0_1788197700710_0.9143842024484123","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@casys/mcp-view-components","version":"0.3.1","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.3.1","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"5de53f0f9c236b2b672a99c3d132729739daf0e7","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.3.1.tgz","fileCount":71,"integrity":"sha512-eni+azUi8p6TP7skoWxcm0jUKGalvY/fZy51Fm8NAIXKZp9jNj0Y0F5Rj01ZPAyOH1TrQlg5njPFWqweCm7GKw==","signatures":[{"sig":"MEUCIQDppLEME72pYw243KLwsJZQ/aWqdn/9bpRAoHxhwWBHxgIgaSBtQ7QiyRwkXD67GJPVz7BivWxQPI+KE8TNP1FrD/Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":290158},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"d623978384ce52aa42bff38f8e981da362745afa","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.2","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.3.1_1788197857300_0.8299389487131918","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@casys/mcp-view-components","version":"0.4.0","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.4.0","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"a1bac0ce1420f8f58f3601fe7ba7d74b8b079078","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.4.0.tgz","fileCount":77,"integrity":"sha512-j+hC7TKBt1//BOr75JGpOJjtwNHM3MvQeywSFaIouXSnkD4xt0QruMGpW1XNJwYYqLfXAFpbEDsW6xxkOmiOJg==","signatures":[{"sig":"MEUCIQDfE6mO/tldT+UPZjMujq14CpSXQhRH+p3qcEpgZqq14wIgGy/qOECBwZhY6tlXjQiU61Lz2eaPCRZrBCv0iQUXv0o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":402616},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"a86e536c321807ed31cac30011480c2e3a1cde50","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.2","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.4.0_1788230335714_0.9655730354734517","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@casys/mcp-view-components","version":"0.5.0","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.5.0","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"a3543ffd5abbbac00e1f3c79b91f502b88daf4c5","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.5.0.tgz","fileCount":77,"integrity":"sha512-zyrkSljsmw6X0VcMCBkT9CiERoX874sFHmowIt3poRFoB0EEt5pqaVfNiPAbwFCfxGxm71vwHyLaXcGzSJ6uRw==","signatures":[{"sig":"MEQCIHmFC6Do9Pq7NWvgNR5VPToTBgMvMZz63vOi2DivpllzAiA5UnWkYKfNjlZnWvBdjxXKt1kWgvrAFWHfiq43CtjI1w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":420363},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"d60f8f5b7d4064cb069c57a6e46941a129188e65","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.2","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.5.0_1788266633943_0.18855568749897533","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@casys/mcp-view-components","version":"0.6.0","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.6.0","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"0f84a576bd1e4f8fd90327b56be3b38deac40556","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.6.0.tgz","fileCount":113,"integrity":"sha512-8vaaLZQgW4jzqIlxjhCziIXfI5lR+EuLHW01yRPZjSWpJ39eWznoVLWJr7pnO5o6TFxejhBvA/AQI14jpUVLUg==","signatures":[{"sig":"MEUCIQDrUS/7Xq+mWSEIkjlVYDWaj4JEg9ss7qjW55GxeHwXywIgbC8S6smXrbNkTkzJrzuZ4vVIrmPqALXEueTTDVKRGu0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":796052},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./fonts":{"types":"./esm/fonts.d.ts","import":"./esm/fonts.js","require":"./script/fonts.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./surface":{"types":"./esm/surface.d.ts","import":"./esm/surface.js","require":"./script/surface.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"f475f636f0d60457c7845ba4cc1e4c6c43be2f22","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.2","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.6.0_1788417935082_0.10874141177107233","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@casys/mcp-view-components","version":"0.7.0","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.7.0","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"e8e15c70f7650cfad9fd1169385c94f064fd819d","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.7.0.tgz","fileCount":137,"integrity":"sha512-g3BVyk5LY0mXuWxx//PDjPj90wQ9RiizVz9piLilQRTLvrEMfxIkqP+z7lDmkZbpX5FaYihjw2AOfM54KWlSTw==","signatures":[{"sig":"MEQCIDFubmJzuAk4A8Pjc633kdIaDO28R5wyeTnGGNDKbXynAiBf2Fuqm8i5wBBoCfEwByOKUjmPQ548R63WsTIEh2/8GA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":837074},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./fonts":{"types":"./esm/fonts.d.ts","import":"./esm/fonts.js","require":"./script/fonts.js"},"./layout":{"types":"./esm/layout.d.ts","import":"./esm/layout.js","require":"./script/layout.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./surface":{"types":"./esm/surface.d.ts","import":"./esm/surface.js","require":"./script/surface.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"55263277e9ef3969f1b690f80590775ceffb194e","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.3","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.7.0_1788526020715_0.3621367134145821","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@casys/mcp-view-components","version":"0.7.1","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.7.1","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"3d4c35daf8dc06dec22b678307cc7c0c2e632349","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.7.1.tgz","fileCount":137,"integrity":"sha512-qGQ7HctoTw2xKUBD2C6ZmF61+eNTsOD2tbMVOVh3gJZYedYY8yFD7Rc/JASR+FXDQQHcYhPSGTw/HcY7euSJ/Q==","signatures":[{"sig":"MEQCIBDgccGNXJTko855fXkMVBsb1JFus4wIhWyliAsJ3+xmAiAs5Gp5H4Zi8ZzDQUVc6AAIIUgEOGfIkfIVyl0U+eUVpg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":842707},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./fonts":{"types":"./esm/fonts.d.ts","import":"./esm/fonts.js","require":"./script/fonts.js"},"./layout":{"types":"./esm/layout.d.ts","import":"./esm/layout.js","require":"./script/layout.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./surface":{"types":"./esm/surface.d.ts","import":"./esm/surface.js","require":"./script/surface.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"342c1b7456c011d3f21cad988f9dde23bcbecae0","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.3","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.7.1_1788533995611_0.4396998223569726","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@casys/mcp-view-components","version":"0.8.0","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"license":"MIT","_id":"@casys/mcp-view-components@0.8.0","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"homepage":"https://github.com/Casys-AI/mcp-server#readme","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"dist":{"shasum":"411db637e4abf0937afc426c20fd2a6f58671555","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.8.0.tgz","fileCount":155,"integrity":"sha512-a179R6Q5yR7Cb9RyvGdzE90UQ7hl8V6KgZ3V6dOLCak1GO0gQ7Yf13VkWDxDQAAXLOjywDcgnrGdCejGSiGGpg==","signatures":[{"sig":"MEUCIE4PzyUEnU51qxxc1T0Tj7shEkSMVQRRSpzSRg1t5xY3AiEA1X5WJ/fAIMkAhZ1CD62hyzTtpF9tf7RfsBN/f9D8ytA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":886971},"main":"./script/mod.js","types":"./esm/mod.d.ts","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./fonts":{"types":"./esm/fonts.d.ts","import":"./esm/fonts.js","require":"./script/fonts.js"},"./layout":{"types":"./esm/layout.d.ts","import":"./esm/layout.js","require":"./script/layout.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./surface":{"types":"./esm/surface.d.ts","import":"./esm/surface.js","require":"./script/surface.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"}},"gitHead":"f9cb8493edfd555c58b9fc6f5601fe444fc78046","_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"repository":{"url":"git+https://github.com/Casys-AI/mcp-server.git","type":"git"},"_npmVersion":"10.9.8","description":"Optional light-first component runtime for small composable MCP App viewers","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@casys/mcp-view":"^0.9.3","@casys/mcp-view-contracts":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/mcp-view-components_0.8.0_1788574542593_0.8517024079556903","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@casys/mcp-view-components","version":"0.9.0","description":"Optional light-first component runtime for small composable MCP App viewers","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"repository":{"type":"git","url":"git+https://github.com/Casys-AI/mcp-server.git"},"license":"MIT","main":"./script/mod.js","module":"./esm/mod.js","exports":{".":{"types":"./esm/mod.d.ts","import":"./esm/mod.js","require":"./script/mod.js"},"./preact":{"types":"./esm/preact.d.ts","import":"./esm/preact.js","require":"./script/preact.js"},"./preact/components":{"types":"./esm/preact-components.d.ts","import":"./esm/preact-components.js","require":"./script/preact-components.js"},"./surface":{"types":"./esm/surface.d.ts","import":"./esm/surface.js","require":"./script/surface.js"},"./layout":{"types":"./esm/layout.d.ts","import":"./esm/layout.js","require":"./script/layout.js"},"./fonts":{"types":"./esm/fonts.d.ts","import":"./esm/fonts.js","require":"./script/fonts.js"}},"dependencies":{"@casys/mcp-view":"^0.9.3","@casys/mcp-view-contracts":"^0.1.0"},"types":"./esm/mod.d.ts","peerDependencies":{"preact":"^10.28.3"},"peerDependenciesMeta":{"preact":{"optional":true}},"_id":"@casys/mcp-view-components@0.9.0","gitHead":"b08802df353bb25d25a1c8d64b22ea61b5287ae0","bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"homepage":"https://github.com/Casys-AI/mcp-server#readme","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-4vJFoTfyBX4Wve7RfsfR9YWt0XjBryGenpamY2AptbBSfsxfA8G+6AhcRImcpbjw+kcchWf+/aLAGRVePVRgJA==","shasum":"8bb95ec37e24dfa84405c0e9f062db91e236d0e2","tarball":"https://registry.npmjs.org/@casys/mcp-view-components/-/mcp-view-components-0.9.0.tgz","fileCount":155,"unpackedSize":895682,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCZHT6QwUa/E3eVnOcy7p7R6DAjTqD1MhzImn7vV0wShgIgB7qrwRQGFkCE96vy8jQ0U+tbnnfzSDalK3uNcSh146g="}]},"_npmUser":{"name":"superworldsavior","email":"erpesle@gmail.com"},"directories":{},"maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-view-components_0.9.0_1788578560059_0.6242557682156678"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T10:09:20.266Z","modified":"2026-09-05T03:22:40.444Z","0.1.0":"2026-08-31T10:09:20.679Z","0.2.0":"2026-08-31T11:47:12.933Z","0.2.1":"2026-08-31T15:34:33.737Z","0.3.0":"2026-08-31T17:35:00.850Z","0.3.1":"2026-08-31T17:37:37.513Z","0.4.0":"2026-09-01T02:38:55.856Z","0.5.0":"2026-09-01T12:43:54.078Z","0.6.0":"2026-09-03T06:45:35.272Z","0.7.0":"2026-09-04T12:47:00.867Z","0.7.1":"2026-09-04T14:59:55.756Z","0.8.0":"2026-09-05T02:15:42.744Z","0.9.0":"2026-09-05T03:22:40.228Z"},"bugs":{"url":"https://github.com/Casys-AI/mcp-server/issues"},"license":"MIT","homepage":"https://github.com/Casys-AI/mcp-server#readme","keywords":["mcp","model-context-protocol","mcp-apps","components","preact"],"repository":{"type":"git","url":"git+https://github.com/Casys-AI/mcp-server.git"},"description":"Optional light-first component runtime for small composable MCP App viewers","maintainers":[{"name":"superworldsavior","email":"erpesle@gmail.com"}],"readme":"# @casys/mcp-view-components\n\nOptional presentation runtime and light-first component kit for MCP Apps. It gives provider-owned\nviewers a shared visual grammar without moving their data, semantics, or rendering authority into\nthe host.\n\nThe intended unit is a small recorded view: one run, artifact, requirement, metric, or other bounded\nobject. A provider may export several whole-view resources; it should not turn one viewer into a\ndashboard that contains every provider capability. In a composed host such as the Digital Thread\nWhiteboard, `chip`, `row`, and `card` densities project the same semantic object while the\nwhole-view App remains the exact viewer opened for that object.\n\n## Package boundary\n\n- `@casys/mcp-view-contracts` is dependency-free and owns serializable contracts.\n- `@casys/mcp-view` owns the MCP App lifecycle and transport.\n- `@casys/mcp-view-components` is optional. Apps that do not want the kit do not import it.\n- Providers resolve references and validate values, units, limits, verdicts, and provenance. The\n  components display those values and never infer them.\n- The host composes and opens recorded views. It does not become a native CAD, Modelica, FEA, or\n  SysML renderer.\n\nThe package root is renderer-neutral and carries no MCP Apps runtime: `@casys/mcp-view` and\n`@modelcontextprotocol/ext-apps` are reached only through the `/surface` entry, which owns the App\nlifecycle. The responsive layout decision and its hooks live in the `/layout` entry, which takes the\nhost context as a value and loads no App runtime. The embedded webfonts are reached only through the\n`/fonts` entry. Preact is an optional peer and is loaded only through the Preact subpaths and\n`/layout`, whose hooks are Preact:\n\n```ts\nimport { defineComponentRegistry, installMcpViewTheme } from \"@casys/mcp-view-components\";\nimport {\n  ArtifactRow,\n  BadgeGroup,\n  Card,\n  CodeBlock,\n  CollectionCard,\n  DrillHint,\n  ElementBody,\n  ElementIdent,\n  ElementLimit,\n  ElementProvenance,\n  ElementReading,\n  InlineCode,\n  IntervalPlot,\n  LimitGauge,\n  NoticeGroup,\n  PathBar,\n  renderStatusMessage,\n  Row,\n  SemanticElement,\n  SemanticList,\n  SeriesChart,\n  Skeleton,\n  Slot3D,\n  Sparkline,\n  StaleBanner,\n  TextInput,\n  TreeList,\n  TypeBadge,\n} from \"@casys/mcp-view-components/preact\";\n```\n\n## Presentation vocabulary\n\nPrimitives:\n\n- `Card`, `Badge`, `BadgeGroup`, `Button`, `Toolbar`, `Stack`, `Row`, `TextInput`, `InlineCode`,\n  `CodeBlock`, `Skeleton`\n- `Metric`, `MetricGrid`, `KeyValueList`, `DataTable`\n- `Message`, `StateMessage`, `EmptyState`, `CrossSelection`, `NoticeGroup`\n\nReusable structures:\n\n- `PathBar` for local navigation inside one bounded view; a path of one item renders nothing. New\n  optional props: `maxVisible` (inline capacity before leading items collapse; default three),\n  `collapsedLabel` (accessible name of the collapsed disclosure), `backLabel` (leading step-out\n  control), and `PathBarItem.detail` (recorded state of a kept level, revealed in the collapsed\n  disclosure).\n- `LimitGauge` for caller-supplied readings, bounds, labels, and tone\n- `ArtifactRow` for immutable artifact identity and literal verification status\n- `DrillHint` for one available drill-down, in direction `\"in-view\"` or `\"to-model\"`. Without a\n  callback the hint degrades to plain text so a host that cannot follow it never advertises a step\n  that does not exist.\n- `TypeBadge` names what kind of view one level is (`\"list\"`, `\"chart\"`, or `\"record\"`); the caller\n  supplies all wording.\n- `StaleBanner` marks surrounding values as recorded earlier without hiding or replacing them. Tone\n  defaults to `\"warning\"`; `\"danger\"` promotes the ARIA role to `alert`.\n- `Slot3D` reserves a bounded area for a provider-owned renderer; without `children` the slot stays\n  visibly reserved. The kit renders no geometry.\n- `TreeList` for a controlled hierarchy with caller-owned type wording and coverage labels;\n  expansion and selection state are fully caller-managed.\n\nNumeric evidence:\n\n- `Sparkline` for the compact shape of one recorded series, readable at chip and row density.\n  Requires at least two finite samples already ordered by the caller.\n- `SeriesChart` for a multi-series plot on a shared finite scale. Each series requires a `mark`\n  field (`\"line\"` or `\"bar\"`): `\"line\"` connects samples with a polyline — an assertion that the\n  quantity existed between them; `\"bar\"` draws each recorded sample as an isolated mark and claims\n  nothing about the interval. The optional `onScrub` callback reports the pointer position on the\n  shared x scale (`undefined` when the pointer leaves); a series with no recorded point at that\n  position is absent from the readout rather than filled. The kit never interpolates, aligns to a\n  nearest neighbour, draws a continuity it has not measured, or invents a value — the provider\n  declares both the mark shape and which sample a position corresponds to.\n- `IntervalPlot` for caller-declared deviation intervals laid out against a shared zero line. The\n  scale must contain zero; every bound and label is caller-supplied.\n\nSemantic composition:\n\n- `SemanticElement` with `chip | row | card` density and kit-owned explicit selection\n- `SemanticList` for a bounded, optionally scrollable group of row-density semantic objects\n- `CollectionCard` composing `Card` and `SemanticList` into one outer-border collection\n- required `ElementIdent`\n- optional `ElementReading` or caller-declared `ElementLimit`, plus `ElementBody`, `ElementVerdict`,\n  and `ElementProvenance`\n- `ElementSection` for one titled group inside the body\n\n`viewer` is deliberately not a `SemanticElement` density. It is the provider's whole-view App,\nusually composed from one `card` plus an optional `PathBar`.\n\n```tsx\n<SemanticElement\n  reference={{ domain: \"cad\", kind: \"artifact\", id: \"bracket.step\" }}\n  density=\"card\"\n  tone=\"warning\"\n  ident={<ElementIdent marker=\"STEP\" label=\"Bracket\" detail=\"revision 4\" />}\n  reading={<ElementReading label=\"Minimum thickness\" value=\"0.84\" unit=\"mm\" />}\n  provenance={<ElementProvenance label=\"SHA-256\" value={digest} />}\n/>;\n```\n\nThe semantic reference is structured but never dereferenced by the component. Likewise, `LimitGauge`\nnever derives whether a value passes a limit, and `ArtifactRow` never claims a digest was verified\nunless the caller supplies that recorded status.\n\nUse `ElementLimit` when the record contains only an authored bound. It displays the supplied\noperator, value, and unit without inventing a measurement, range, satisfaction state, or verdict.\n\n## System states\n\nThree components express a view's readiness without hiding or fabricating content.\n\n`Skeleton` is a frame-first loading placeholder: it draws the structure before values arrive so\nlayout does not shift on load. The caller supplies an accessible label and an optional line count\n(default three).\n\n`StaleBanner` keeps dated values visible while flagging that the snapshot is not current. The caller\nformats the message, including the recorded instant. The banner never refetches or replaces a value\nwith a gap.\n\n`DrillHint` without a callback degrades to plain text. A host that cannot follow a drill-down step\nomits `onActivate`; the hint stays visible but renders no affordance. Providers declare every\navailable next step without advertising actions the host cannot execute.\n\n`NoticeGroup` gathers short notices under a single severity heading. It renders nothing when there\nare no items and no `omittedLabel`, so the caller never has to guard the call site. Truncation is\nstated by the caller via `omittedLabel`: the group displays only the items it was handed and never\ncounts what it was not given.\n\n## Imperative bridge\n\n`renderStatusMessage(detail, options?)` renders a `StateMessage` into a real DOM node and returns\nit. `defineView` must return a native element, so every viewer built on it previously wrote its own\nPreact-to-DOM bridge; those bridges drifted in tone, ARIA role, and class. `renderStatusMessage` is\nthat bridge, made canonical. Without `container` it returns the rendered `.mcp-view-state` element,\nso what you mount carries the class, the tone and the alert role; `className` lands on that same\nnode. Pass `container` to render into a node you already own, which is then what comes back. It\nlives in the pure presentation module `@casys/mcp-view-components/preact/components` and does not\nimport `@casys/mcp-view`, so it is reachable from any entry that does not need the surface\nlifecycle.\n\nWithout `container` it returns the rendered `.mcp-view-state` element; with one it renders into the\nnode you passed and returns that.\n\n## Viewer layout\n\n`useViewerLayout(hints, options?)` (`/layout` entry) decides one of three treatments for one viewer\nroot — `\"wide\" | \"panel\" | \"mobile\"` — from the host's word first, the browser's measure as fallback\nand an explicit override on top. The three treatments are two contexts under one breakpoint\n(`NARROW_BREAKPOINT`, 480px), not a width scale: under it, a finger without hover picks `mobile`,\nanything else `panel`; a tablet under a finger but with room keeps `wide`. The hook measures the\nelement you attach `ref` to, not the window, because an iframe's width says nothing about the\nscreen's; the host's declared `containerDimensions.width` (then `maxWidth`) outranks that measure\nbecause it describes the room actually granted. `boundsStyle` bounds the root on the host's declared\n`height` (else `maxHeight`) instead of `100vh`, and is `undefined` when the host declares none so\nthe viewer stays intrinsic and lets the host auto-resize.\n\n```tsx\nimport { useViewerLayout } from \"@casys/mcp-view-components/layout\";\n\nconst Viewer = ({ data, context }: PreactSurfaceComponentProps<RunModel>) => {\n  const { ref, layout, boundsStyle } = useViewerLayout<HTMLDivElement>(context.hostContext);\n  return (\n    <div ref={ref} data-layout={layout} style={boundsStyle}>\n      {layout === \"wide\"\n        ? <RunTable data={data} />\n        : <RunRows data={data} touch={layout === \"mobile\"} />}\n    </div>\n  );\n};\n```\n\n`hints` is any `{ deviceCapabilities?, containerDimensions? }` — the kit's `McpViewHostContext`\nsatisfies it structurally, so the entry never imports `@casys/mcp-view`. Touch follows the host's\n`deviceCapabilities` (`touch && hover !== true`: a touch-screen laptop driven by a mouse is no\nphone) and only falls back to `matchMedia(\"(pointer: coarse)\")` when the host says nothing.\n`?layout=mobile` in the page query string forces a treatment for reviewing it without the matching\ndevice; pass `{ forced: null }` to ignore the URL, or `{ forced: \"panel\" }` to pin one. The decision\nitself — `resolveViewerLayout`, `layoutWidth`, `touchInput`, `layoutFromSearch`, `viewerBoundsStyle`\n— is exported pure, and the two measuring hooks, `useContainerWidth()` and `useCoarsePointer()`, are\nexported on their own.\n\n## Focused viewers and technical details\n\n`FocusedView` keeps one primary visualization or reading prominent and puts optional technical\nmetadata behind a closed `Disclosure`. Its `status` slot stays outside that disclosure: warnings,\nunavailable evidence and literal verification state remain visible. The existing surface supplies\nthe frame, so the preset adds no card, shadow or application chrome.\n\n```tsx\nimport { FocusedView } from \"@casys/mcp-view-components/preact/components\";\n\n<FocusedView\n  label={labels.geometry}\n  hostContext={context.hostContext}\n  status={<StateMessage title={recorded.status}>{recorded.message}</StateMessage>}\n  primary={<GeometryCanvas geometry={recorded.geometry} />}\n  detailsLabel={labels.technicalDetails}\n  details={<KeyValueList layout=\"facts\" items={recorded.provenance} />}\n/>;\n```\n\nThe preset calls `useViewerLayout` with the host hints and applies its container ref, `data-layout`\nand height bounds. At a narrow desktop width it uses `panel`; under a finger it uses `mobile` with a\nlarger disclosure target. Pass `layout` only to review a forced treatment. The primary remains\nprovider-owned; the preset never invents a preview, a status or an evidence value.\n\nUse `Disclosure` on its own for an inline technical section: `label` is supplied by the caller,\n`children` hold the detail, and optional `open` / `onToggle(open)` expose its native state. Native\n`details` / `summary` provide keyboard behavior and expanded state. Omit `open` to start closed.\n`FocusedView` requires a `detailsLabel` whenever it receives `details`; omit both to render no\ntechnical control. Keep consequential state in `status` or `primary`.\n\n## Theme\n\n`installMcpViewTheme()` installs the shared CSS once. The defaults are light-first and include an\nexplicit dark mapping (`:root[data-theme=\"dark\"]`, or `prefers-color-scheme` unless the host pins\n`data-theme=\"light\"`). The surface is the one frame a viewer shows — border, radius, panel and a 2px\naccent→brand rule — and its stacked components are separated by hairlines, so a `stack` surface\ndefaults to `gap: \"none\"`. Inside, values sit in hairline cells rather than filled tiles.\n\nTypography has three roles: the heading face for titles and large values, the body face for prose,\nand the mono face for labels, keys, units, markers, verdicts, provenance and identifiers. Sizes come\nfrom a px scale (`--mcp-view-size-micro` 10px … `--mcp-view-size-metric` 22px) so a host that\nrescales `rem` cannot squash the datasheet. The preferred faces mirror the v2 reference\n(`Space Grotesk`, `Work Sans`, `JetBrains Mono`) and fall back to native families; the theme itself\nneither embeds fonts nor makes a network font request. Apps can override the stable variables\nexported as `MCP_VIEW_THEME_TOKENS`:\n\n```css\n:root {\n  --mcp-view-accent: #0d7c8a;\n  --mcp-view-brand: #8a4fa3;\n  --mcp-view-font-heading: \"Space Grotesk\", \"Avenir Next\", sans-serif;\n  --mcp-view-font-body: \"Work Sans\", Avenir, sans-serif;\n  --mcp-view-font-mono: \"JetBrains Mono\", \"SFMono-Regular\", monospace;\n  --mcp-view-radius: 8px;\n}\n```\n\n### Embedded fonts\n\nA viewer bundled into one HTML file and opened inside a host iframe usually has neither network\naccess nor a CSP that allows font requests, so the preferred faces would silently fall back. The\n`/fonts` entry embeds them (three variable faces, latin subset, ~137 KB of base64 woff2, SIL Open\nFont License 1.1). It is opt-in: import it only from the viewer bundle that wants it.\n\n```ts\nimport { installMcpViewTheme } from \"@casys/mcp-view-components\";\nimport { installMcpViewFonts } from \"@casys/mcp-view-components/fonts\";\n\ninstallMcpViewFonts();\ninstallMcpViewTheme();\n```\n\n`MCP_VIEW_FONT_FAMILIES` lists the families, their weight range and the theme role each serves. The\npayload lives in `src/fonts-data.ts`, generated by `deno task fonts:fetch` and drift-checked by\n`deno task fonts:check`.\n\n## Surface App\n\n`startSurfaceApp()` (`/surface` entry) runs the whole result-driven App lifecycle for a component\nregistry: it opens on a loading status, projects every tool result into one `SurfaceDisplayState`,\nmounts the host-selected surface (or the registry default), remounts it when the host context\nchanges, guards overtaken mounts, and converts every failure into a status instead of a blank page.\nA viewer supplies its registry, the projection and how a status is rendered; everything else —\n`strict`, `theme`, the status labels, `onError`, `viewerSession` — has a documented default.\n\n```ts\nimport { createTranslator } from \"@casys/mcp-view-components\";\nimport { startSurfaceApp } from \"@casys/mcp-view-components/surface\";\n\nconst messages = createTranslator({\n  defaultLocale: \"en\",\n  messages: {\n    solvingTitle: \"Solving\",\n    solvingMessage: \"The run is still open.\",\n  },\n  translations: {\n    fr: {\n      solvingTitle: \"Résolution\",\n      solvingMessage: \"L’exécution est encore ouverte.\",\n    },\n  },\n});\n\nconst app = await startSurfaceApp<RunModel>({\n  root,\n  info: { name: \"Run viewer\", version: \"1.0.0\" },\n  registry,\n  strict: true,\n  documentLanguage: messages.locale,\n  fromToolResult: async (result, host) => {\n    if (result.isError) return { kind: \"error\", message: toolErrorMessage(result) };\n    const model = parseRun(result.structuredContent);\n    if (!model) return { kind: \"empty\" };\n    if (model.pending) {\n      return {\n        kind: \"notice\",\n        title: (locale) => messages(locale)(\"solvingTitle\"),\n        message: (locale) => messages(locale)(\"solvingMessage\"),\n        busy: true,\n      };\n    }\n    return { kind: \"result\", result: model };\n  },\n  renderStatus: (status) => renderMyStatus(status),\n});\n```\n\nThe projection may return a promise and may read server resources through `host.readServerResource`.\nWithout a projection, `validate` (a type guard) is applied to `structuredContent` with a JSON-text\nfallback; passing both is refused with `SURFACE_APP_PROJECTION_CONFLICT`.\n\nEvery non-result state reaches `renderStatus` as one `SurfaceStatus` — `kind`, `message`, `title?`,\n`tone`, `busy` and the caller's optional `code`:\n\n| `kind`             | When                                             | `tone`    | `busy`  |\n| ------------------ | ------------------------------------------------ | --------- | ------- |\n| `loading`          | before the first result, and on tool input       | `info`    | `true`  |\n| `empty`            | `{ kind: \"empty\" }` or a rejected `validate`     | `neutral` | `false` |\n| `error`            | `{ kind: \"error\" }`, a rejected session          | `danger`  | `false` |\n| `notice`           | `{ kind: \"notice\" }`, defaults `neutral`/`false` | given     | given   |\n| `surface-required` | component-only registry without a host selection | `warning` | `false` |\n\n`code` is passed through from a `notice` or `error` state and never invented, so a viewer can key\nits own recovery hints on it. A projection that throws becomes a `Result rejected` error status and\nwipes the previous result; to keep the last good values under the failure, return a `result` that\ncarries it — the scaffold does exactly that. A mount that fails or a malformed host selection stays\non the surface route as `Surface failed` or `Surface invalid`, so a corrected selection can recover\nin place. All three are reported to `onError` (default `console.error`) and the App keeps running.\n\n`surfaceFor(data)` lets a result own its composition: a returned surface is mounted as is, with\nneither the host selection nor the registry default consulted, so a recorded session that replaces\nthe whole read model composes itself while live results keep following the host. `undefined` keeps\nthe host flow. It is asked on every mount of that result, remounts included; a malformed owned\nsurface stays on the route as `Surface invalid` and names its owner. `onTeardown` runs once when the\nhost tears the App down or `dispose()` runs, before the surface is disposed — the place to close\nwhat the App holds outside its surface, such as a bridge to the parent page. Its throw goes to\n`onError`.\n\nThe projection and the session subscription are registered before the App connects, so nothing the\nhost sends during the handshake is lost. The host context is re-applied on every\n`hostcontextchanged`, including the notifications the runtime replays from the handshake; the\nsurface is remounted only while the surface route holds a result (a surface-route failure included)\nand the context object actually moved — never while a status is shown or a transition is in flight.\n`theme: false` skips the theme install at boot only — primitives still install it when they mount.\n\nFor a renderer that already follows the CSS theme tokens, `themeUpdates: \"in-place\"` keeps that\nrenderer mounted when only the host theme changes. This preserves local camera or interaction state.\nHosts that resend a complete JSON snapshot with new object identities but the same non-theme values\ndo not remount: comparison is structural (object key order ignored, array order kept). The default\nremains `\"remount\"`; do not opt in if a component reads theme colors only at mount. Locale,\ndimensions, styles, component selection and other value changes still remount normally in either\nmode.\n\nGeneric loading, empty and failure headings follow the host locale, including `Result rejected` and\n`Session rejected` after a locale change while that status is visible. `loadingLabel`, `emptyLabel`\nand `surfaceRequiredLabel` also accept `(locale) => string`. `error` and `notice` `title`/`message`\naccept the same `SurfaceLabel` callbacks, resolved on each visible status render so a provider\ndictionary can follow the host locale without re-running `fromToolResult`, session projection or\nresource reads. Literal titles, messages and `code` stay unchanged.\n`documentLanguage: messages.locale` sets `document.documentElement.lang` to the selected dictionary\nat boot and on locale changes; omit it to leave the document language untouched. The `messages`\noption accepts a `createTranslator` catalog for additional languages. Domain values, contract\nstates, raw provider messages, codes, identifiers, numbers and units remain literal. Tool-result and\nsession projections receive `host.locale` for interface wording, never for interpreting or\nvalidating domain values.\n\n`startPreactSurfaceApp()` (`/preact`) is the same App with statuses rendered through\n`renderStatusMessage`, plus `statusClassName` for viewer-owned styling hooks; its shell keeps the\n`mcp-view-preact-surface` class 0.5 viewers style (the core default is `mcp-view-surface-shell`).\nBoth return a `SurfaceAppHandle` whose `show(state)` drives the App from outside the MCP lifecycle\nand whose `dispose()` tears it down. Option conflicts throw `SurfaceAppError`, a `TypeError` with a\nstable `code` (`SURFACE_APP_PROJECTION_CONFLICT`) and a `data.recovery` sentence; `show()` on a\nhandle the host already tore down rejects with `SURFACE_APP_CLOSED`.\n\nWhole-view recorded sessions are declared in `@casys/mcp-view-contracts` and consumed through the\ncore resource lifecycle. `viewerSession` pairs a `validate` guard with a `toState` projection; the\nApp subscribes before it connects and the runtime buffers what arrives during the handshake, so a\none-shot session cannot be lost and no individual component claims `viewer.session.apply`. The 0.6\n`validateSession`/`mapSessionToData`/`onInvalidSession` options of `startPreactSurfaceApp()` are\ngone in 0.7.0; `viewerSession: { validate, toState, onInvalid }` is the one form.\n\n## Common compositions\n\nThe kit stays small and non-prescriptive, leaving assembly to the caller. When multiple viewers\nbuild the same assembly from the same primitives, this section is what they should have found first.\n\n### Named quantity section\n\n`Card` + `MetricGrid` carries one named group of measurements. Repeat the pattern for each domain\nregion; `EmptyState` handles the no-data case without shifting layout.\n\n```tsx\n<Card title=\"Load margins\">\n  {items.length === 0 ? <EmptyState>No values recorded.</EmptyState> : <MetricGrid items={items} />}\n</Card>;\n```\n\n### Datasheet body\n\nA card-density `SemanticElement` reads as a datasheet only while every figure has one place. The\nreadings strip is the headline, so it shows either every measurement or none — a subset picked by\nposition is not a headline. Its tiles wrap into rows and a short last row widens them, so five\nreadings are four and one wide, never four and a hole. The body is `ElementSection`s, each naming\nwhat it holds: measurements in a `DataTable` (one row per quantity, the unit in its own column),\ndocumentary facts in a `KeyValueList layout=\"facts\"`, artifacts in an `ArtifactRow`. Labels are\nworded for the reader, never raw field names. One fingerprint closes the sheet in\n`ElementProvenance`; nothing shown in a section is repeated there.\n\n```tsx\n<SemanticElement\n  reference={reference}\n  density=\"card\"\n  ident={<ElementIdent marker=\"OP\" label=\"Operating point\" detail=\"Admitted result · r150\" />}\n  reading={observables.length <= READING_STRIP_LIMIT ? observables.map(toReading) : []}\n  body={\n    <ElementBody>\n      {observables.length > READING_STRIP_LIMIT && (\n        <ElementSection title=\"Observables\">\n          <DataTable\n            label=\"Observables\"\n            rows={observables}\n            columns={QUANTITY_COLUMNS}\n            rowKey={rowKey}\n          />\n        </ElementSection>\n      )}\n      <ElementSection title=\"Provenance\">\n        <KeyValueList layout=\"facts\" items={provenanceFacts} />\n        <ArtifactRow label=\"Admitted result\" uri={artifact.id} fingerprint={artifact.fingerprint} />\n      </ElementSection>\n    </ElementBody>\n  }\n  provenance={<ElementProvenance label=\"Projection\" value={projectionFingerprint} />}\n/>;\n```\n\n### Artifact collection\n\n`CollectionCard` + `ArtifactRow` keeps a single outer border for a bounded list of immutable\nartifacts. Thread the count through `eyebrow` or `actions`; `EmptyState` fills the list body when\nthere is nothing to show. `CollectionCard` is available since 0.3.x; the `eyebrow` slot on `Card`\naccepts any `ComponentChildren`, so a plain count string requires no extra component.\n\n```tsx\n<CollectionCard\n  label=\"Build artifacts\"\n  title=\"Artifacts\"\n  eyebrow={artifacts.length > 0 ? `${artifacts.length} items` : undefined}\n>\n  {artifacts.length === 0\n    ? <EmptyState>No artifacts recorded.</EmptyState>\n    : artifacts.map((a) => (\n      <ArtifactRow\n        key={a.uri}\n        label={a.label}\n        uri={a.uri}\n        verification={a.verification}\n      />\n    ))}\n</CollectionCard>;\n```\n\n## Contributing interface translations\n\nEnglish is the default and reference language. French is an optional existing translation;\nadditional languages are contributions, not a prerequisite for building or improving a viewer.\n\n`createTranslator` is a small renderer-neutral dictionary helper from the package root. Keep stable\nkeys in a complete base dictionary, and add language dictionaries as partial overrides. Select the\ntranslator from the current host locale when rendering, so the same recorded result can change its\ninterface language without changing its data.\n\n```ts\nimport { createTranslator } from \"@casys/mcp-view-components\";\n\nconst en = {\n  technicalDetails: \"Technical details\",\n  revisionLabel: \"Revision {revision}\",\n};\nconst fr: Partial<Record<keyof typeof en, string>> = {\n  technicalDetails: \"Détails techniques\",\n  revisionLabel: \"Révision {revision}\",\n};\nconst messages = createTranslator({ defaultLocale: \"en\", messages: en, translations: { fr } });\nconst t = messages(context.hostContext.locale);\nt(\"technicalDetails\");\nt(\"revisionLabel\", { revision: 17 });\nmessages.locale(\"fr-CA\"); // \"fr\" — the dictionary actually selected\n```\n\nLookup falls back **per key** through the exact locale, its language parents, then the base\ndictionary: with an English base, `fr-CA` → `fr` → English. A missing entry in a partial dictionary\ndoes not hide the base text. An absent or invalid host locale uses the configured default locale;\nthere is no global mutable locale. `messages.locale(hostLocale)` uses that same chain and returns\nthe exact registered locale, the matched parent, or the canonical default — pass it as\n`documentLanguage` so `document.documentElement.lang` names the selected dictionary. Keep\ninterpolation names such as `{revision}` intact. Render returned messages as text, never as HTML.\n\nTranslate interface labels and helper text only. Preserve authored names, payload values, units,\nidentifiers, digests, server messages and literal contract states such as `documentary`,\n`unverified`, `unresolved` or `TRACE GAP`. Use `Intl.NumberFormat` and `Intl.DateTimeFormat` with\nthe host locale for presentation; formatting must not convert units or overwrite the stored\nevidence.\n\nFor a new locale contribution, use this short PR checklist:\n\n- Name the locale tag and the dictionary being extended (shared interface or a particular MCP).\n- Keep existing keys stable; add any new key to the base dictionary first.\n- List deliberately missing translations and preserve every interpolation placeholder.\n- Include one small example showing a translated label and fallback for an untranslated key.\n- Check the changed wording in a narrow viewer, including accessible labels and technical details.\n- Confirm that authored data and contract states retain their original bytes and meaning.\n\nThe kit exports its English and French interface dictionaries as `MCP_VIEW_MESSAGES_EN` and\n`MCP_VIEW_MESSAGES_FR`. MCPs keep their domain-specific interface dictionaries beside their viewers;\nthey can reuse the same helper without importing a new localization runtime.\n\n## Result-viewer scaffold (Deno/JSR only)\n\nThe project generator intentionally uses Deno filesystem APIs and `deno fmt`. The generated\n`src/main.ts` is a component registry plus one `fromToolResult` projection handed to\n`startSurfaceApp()` from `@casys/mcp-view-components/surface`; it hand-rolls no App lifecycle. Its\n`build.ts` accepts `MCP_VIEW_MODULE` and `MCP_VIEW_COMPONENTS_MODULE` overrides (the `mod.ts` of a\nlocal checkout); the `/surface` entry is derived from the latter unless\n`MCP_VIEW_COMPONENTS_SURFACE_MODULE` names it. Run the generator from JSR:\n\n```sh\ndeno run -A jsr:@casys/mcp-view-components@0.9.0/scaffold result-viewer ./result-viewer\n```\n\nThe npm package contains only the runtime and presentation entry points. It does not export or ship\n`@casys/mcp-view-components/scaffold`; Node ESM imports and CommonJS requires of that subpath are\nexpected to fail with `ERR_PACKAGE_PATH_NOT_EXPORTED` rather than loading a Deno-only module.\n","readmeFilename":"README.md"}