@theokit/ui 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1325 -0
- package/DESIGN.md +456 -0
- package/LICENSE +201 -0
- package/NOTICE +38 -0
- package/README.md +467 -0
- package/dist/chunk-27ENTTY7.js +146 -0
- package/dist/chunk-27ENTTY7.js.map +1 -0
- package/dist/chunk-2H6TQELG.js +33 -0
- package/dist/chunk-2H6TQELG.js.map +1 -0
- package/dist/chunk-2L6MRJD4.js +120 -0
- package/dist/chunk-2L6MRJD4.js.map +1 -0
- package/dist/chunk-2Y5V2PAL.js +80 -0
- package/dist/chunk-2Y5V2PAL.js.map +1 -0
- package/dist/chunk-34NAFDVL.js +46 -0
- package/dist/chunk-34NAFDVL.js.map +1 -0
- package/dist/chunk-36KJGXEK.js +112 -0
- package/dist/chunk-36KJGXEK.js.map +1 -0
- package/dist/chunk-3BMYYNN6.js +124 -0
- package/dist/chunk-3BMYYNN6.js.map +1 -0
- package/dist/chunk-3OHV7EEI.js +34 -0
- package/dist/chunk-3OHV7EEI.js.map +1 -0
- package/dist/chunk-3QKTS6F5.js +88 -0
- package/dist/chunk-3QKTS6F5.js.map +1 -0
- package/dist/chunk-3TBXLYNM.js +42 -0
- package/dist/chunk-3TBXLYNM.js.map +1 -0
- package/dist/chunk-4AM2HSXU.js +67 -0
- package/dist/chunk-4AM2HSXU.js.map +1 -0
- package/dist/chunk-4BCGKM65.js +44 -0
- package/dist/chunk-4BCGKM65.js.map +1 -0
- package/dist/chunk-4D3JILQX.js +145 -0
- package/dist/chunk-4D3JILQX.js.map +1 -0
- package/dist/chunk-4EJU2GBG.js +48 -0
- package/dist/chunk-4EJU2GBG.js.map +1 -0
- package/dist/chunk-4WKO3G5C.js +110 -0
- package/dist/chunk-4WKO3G5C.js.map +1 -0
- package/dist/chunk-53XPKI7Q.js +97 -0
- package/dist/chunk-53XPKI7Q.js.map +1 -0
- package/dist/chunk-55TDVDPG.js +58 -0
- package/dist/chunk-55TDVDPG.js.map +1 -0
- package/dist/chunk-56BJLFW7.js +26 -0
- package/dist/chunk-56BJLFW7.js.map +1 -0
- package/dist/chunk-5HOQLE6Y.js +35 -0
- package/dist/chunk-5HOQLE6Y.js.map +1 -0
- package/dist/chunk-5TY3NYF5.js +144 -0
- package/dist/chunk-5TY3NYF5.js.map +1 -0
- package/dist/chunk-5VOSCJKQ.js +92 -0
- package/dist/chunk-5VOSCJKQ.js.map +1 -0
- package/dist/chunk-65NVO6TK.js +171 -0
- package/dist/chunk-65NVO6TK.js.map +1 -0
- package/dist/chunk-6A5TPCKP.js +64 -0
- package/dist/chunk-6A5TPCKP.js.map +1 -0
- package/dist/chunk-6CO4LEXZ.js +41 -0
- package/dist/chunk-6CO4LEXZ.js.map +1 -0
- package/dist/chunk-6FVUPNPG.js +56 -0
- package/dist/chunk-6FVUPNPG.js.map +1 -0
- package/dist/chunk-76YWTIWK.js +106 -0
- package/dist/chunk-76YWTIWK.js.map +1 -0
- package/dist/chunk-7EI7424P.js +78 -0
- package/dist/chunk-7EI7424P.js.map +1 -0
- package/dist/chunk-AHTVYOPQ.js +26 -0
- package/dist/chunk-AHTVYOPQ.js.map +1 -0
- package/dist/chunk-AJTJNHKK.js +85 -0
- package/dist/chunk-AJTJNHKK.js.map +1 -0
- package/dist/chunk-AMT3CPMC.js +155 -0
- package/dist/chunk-AMT3CPMC.js.map +1 -0
- package/dist/chunk-AX5EH73R.js +59 -0
- package/dist/chunk-AX5EH73R.js.map +1 -0
- package/dist/chunk-B3VAJSZ2.js +35 -0
- package/dist/chunk-B3VAJSZ2.js.map +1 -0
- package/dist/chunk-B4CQMQ64.js +25 -0
- package/dist/chunk-B4CQMQ64.js.map +1 -0
- package/dist/chunk-BMRZXT5T.js +115 -0
- package/dist/chunk-BMRZXT5T.js.map +1 -0
- package/dist/chunk-BYZ6OFH4.js +73 -0
- package/dist/chunk-BYZ6OFH4.js.map +1 -0
- package/dist/chunk-C55VUQ7N.js +156 -0
- package/dist/chunk-C55VUQ7N.js.map +1 -0
- package/dist/chunk-D4GEAV4C.js +91 -0
- package/dist/chunk-D4GEAV4C.js.map +1 -0
- package/dist/chunk-DC43CHAM.js +152 -0
- package/dist/chunk-DC43CHAM.js.map +1 -0
- package/dist/chunk-DKCRLN35.js +92 -0
- package/dist/chunk-DKCRLN35.js.map +1 -0
- package/dist/chunk-DN5BUDBI.js +86 -0
- package/dist/chunk-DN5BUDBI.js.map +1 -0
- package/dist/chunk-DOLKDYMS.js +88 -0
- package/dist/chunk-DOLKDYMS.js.map +1 -0
- package/dist/chunk-DW34WXCG.js +28 -0
- package/dist/chunk-DW34WXCG.js.map +1 -0
- package/dist/chunk-DZAAKHGZ.js +135 -0
- package/dist/chunk-DZAAKHGZ.js.map +1 -0
- package/dist/chunk-E4IRSSHO.js +116 -0
- package/dist/chunk-E4IRSSHO.js.map +1 -0
- package/dist/chunk-E67WQXBV.js +104 -0
- package/dist/chunk-E67WQXBV.js.map +1 -0
- package/dist/chunk-EG6IHP3H.js +128 -0
- package/dist/chunk-EG6IHP3H.js.map +1 -0
- package/dist/chunk-EO7LOXG2.js +82 -0
- package/dist/chunk-EO7LOXG2.js.map +1 -0
- package/dist/chunk-EWDN56AS.js +24 -0
- package/dist/chunk-EWDN56AS.js.map +1 -0
- package/dist/chunk-F5P5P2SC.js +141 -0
- package/dist/chunk-F5P5P2SC.js.map +1 -0
- package/dist/chunk-FAWPRZTM.js +79 -0
- package/dist/chunk-FAWPRZTM.js.map +1 -0
- package/dist/chunk-FGYJ2WPX.js +36 -0
- package/dist/chunk-FGYJ2WPX.js.map +1 -0
- package/dist/chunk-GBG3I5I5.js +46 -0
- package/dist/chunk-GBG3I5I5.js.map +1 -0
- package/dist/chunk-GDMCDW66.js +19 -0
- package/dist/chunk-GDMCDW66.js.map +1 -0
- package/dist/chunk-H6HSQCOW.js +80 -0
- package/dist/chunk-H6HSQCOW.js.map +1 -0
- package/dist/chunk-HDM4RCIF.js +111 -0
- package/dist/chunk-HDM4RCIF.js.map +1 -0
- package/dist/chunk-HNTOGGVD.js +77 -0
- package/dist/chunk-HNTOGGVD.js.map +1 -0
- package/dist/chunk-HQW2ABO4.js +28 -0
- package/dist/chunk-HQW2ABO4.js.map +1 -0
- package/dist/chunk-HRDRGZ2Y.js +76 -0
- package/dist/chunk-HRDRGZ2Y.js.map +1 -0
- package/dist/chunk-HUOVA7SF.js +83 -0
- package/dist/chunk-HUOVA7SF.js.map +1 -0
- package/dist/chunk-ITA3SNOR.js +133 -0
- package/dist/chunk-ITA3SNOR.js.map +1 -0
- package/dist/chunk-IYNUPG2G.js +61 -0
- package/dist/chunk-IYNUPG2G.js.map +1 -0
- package/dist/chunk-JJ65ZI4P.js +199 -0
- package/dist/chunk-JJ65ZI4P.js.map +1 -0
- package/dist/chunk-JRBGZ6NI.js +106 -0
- package/dist/chunk-JRBGZ6NI.js.map +1 -0
- package/dist/chunk-K45OO62F.js +108 -0
- package/dist/chunk-K45OO62F.js.map +1 -0
- package/dist/chunk-KDTKA667.js +67 -0
- package/dist/chunk-KDTKA667.js.map +1 -0
- package/dist/chunk-KI7KZBSN.js +142 -0
- package/dist/chunk-KI7KZBSN.js.map +1 -0
- package/dist/chunk-KOJ7XOPZ.js +87 -0
- package/dist/chunk-KOJ7XOPZ.js.map +1 -0
- package/dist/chunk-KQTHJ22B.js +82 -0
- package/dist/chunk-KQTHJ22B.js.map +1 -0
- package/dist/chunk-KRC43RZR.js +77 -0
- package/dist/chunk-KRC43RZR.js.map +1 -0
- package/dist/chunk-LJQOEGQ2.js +116 -0
- package/dist/chunk-LJQOEGQ2.js.map +1 -0
- package/dist/chunk-LKRNUSKZ.js +149 -0
- package/dist/chunk-LKRNUSKZ.js.map +1 -0
- package/dist/chunk-LLL7QQ52.js +76 -0
- package/dist/chunk-LLL7QQ52.js.map +1 -0
- package/dist/chunk-LQ4B5X4Y.js +56 -0
- package/dist/chunk-LQ4B5X4Y.js.map +1 -0
- package/dist/chunk-M3FSLEHQ.js +76 -0
- package/dist/chunk-M3FSLEHQ.js.map +1 -0
- package/dist/chunk-M5G3O6H6.js +57 -0
- package/dist/chunk-M5G3O6H6.js.map +1 -0
- package/dist/chunk-M6JIC5PU.js +81 -0
- package/dist/chunk-M6JIC5PU.js.map +1 -0
- package/dist/chunk-N2HJ3SLS.js +186 -0
- package/dist/chunk-N2HJ3SLS.js.map +1 -0
- package/dist/chunk-NGZWBFTP.js +45 -0
- package/dist/chunk-NGZWBFTP.js.map +1 -0
- package/dist/chunk-OAKCXT35.js +34 -0
- package/dist/chunk-OAKCXT35.js.map +1 -0
- package/dist/chunk-OSD3U3HT.js +54 -0
- package/dist/chunk-OSD3U3HT.js.map +1 -0
- package/dist/chunk-OUXESQ2R.js +42 -0
- package/dist/chunk-OUXESQ2R.js.map +1 -0
- package/dist/chunk-OY2LJHMJ.js +43 -0
- package/dist/chunk-OY2LJHMJ.js.map +1 -0
- package/dist/chunk-OYEZR4CN.js +221 -0
- package/dist/chunk-OYEZR4CN.js.map +1 -0
- package/dist/chunk-P57HUMAE.js +66 -0
- package/dist/chunk-P57HUMAE.js.map +1 -0
- package/dist/chunk-P6Y2PI6L.js +82 -0
- package/dist/chunk-P6Y2PI6L.js.map +1 -0
- package/dist/chunk-PA7TDXUQ.js +51 -0
- package/dist/chunk-PA7TDXUQ.js.map +1 -0
- package/dist/chunk-PPBGGNPV.js +112 -0
- package/dist/chunk-PPBGGNPV.js.map +1 -0
- package/dist/chunk-PRH4HKND.js +48 -0
- package/dist/chunk-PRH4HKND.js.map +1 -0
- package/dist/chunk-PSPAZJUQ.js +32 -0
- package/dist/chunk-PSPAZJUQ.js.map +1 -0
- package/dist/chunk-Q5G5CGZ2.js +170 -0
- package/dist/chunk-Q5G5CGZ2.js.map +1 -0
- package/dist/chunk-QDAF3LP7.js +89 -0
- package/dist/chunk-QDAF3LP7.js.map +1 -0
- package/dist/chunk-QGVIGNJ3.js +37 -0
- package/dist/chunk-QGVIGNJ3.js.map +1 -0
- package/dist/chunk-QNUITYSY.js +68 -0
- package/dist/chunk-QNUITYSY.js.map +1 -0
- package/dist/chunk-QSWVN3RT.js +116 -0
- package/dist/chunk-QSWVN3RT.js.map +1 -0
- package/dist/chunk-QTLQZ7OJ.js +110 -0
- package/dist/chunk-QTLQZ7OJ.js.map +1 -0
- package/dist/chunk-QYAMLIG2.js +84 -0
- package/dist/chunk-QYAMLIG2.js.map +1 -0
- package/dist/chunk-REILH4XF.js +128 -0
- package/dist/chunk-REILH4XF.js.map +1 -0
- package/dist/chunk-S6SSK6QX.js +80 -0
- package/dist/chunk-S6SSK6QX.js.map +1 -0
- package/dist/chunk-SA7ED3PN.js +68 -0
- package/dist/chunk-SA7ED3PN.js.map +1 -0
- package/dist/chunk-SIJOEM4N.js +55 -0
- package/dist/chunk-SIJOEM4N.js.map +1 -0
- package/dist/chunk-SLOKAAH2.js +70 -0
- package/dist/chunk-SLOKAAH2.js.map +1 -0
- package/dist/chunk-TR6NPSMX.js +85 -0
- package/dist/chunk-TR6NPSMX.js.map +1 -0
- package/dist/chunk-TSZ5DEAT.js +106 -0
- package/dist/chunk-TSZ5DEAT.js.map +1 -0
- package/dist/chunk-TUNVF45W.js +127 -0
- package/dist/chunk-TUNVF45W.js.map +1 -0
- package/dist/chunk-TXOBNSQ5.js +63 -0
- package/dist/chunk-TXOBNSQ5.js.map +1 -0
- package/dist/chunk-U44DRLMM.js +88 -0
- package/dist/chunk-U44DRLMM.js.map +1 -0
- package/dist/chunk-U4THNRV5.js +114 -0
- package/dist/chunk-U4THNRV5.js.map +1 -0
- package/dist/chunk-UAZOFC4W.js +72 -0
- package/dist/chunk-UAZOFC4W.js.map +1 -0
- package/dist/chunk-UGKI466V.js +12 -0
- package/dist/chunk-UGKI466V.js.map +1 -0
- package/dist/chunk-VM4RMQQN.js +11 -0
- package/dist/chunk-VM4RMQQN.js.map +1 -0
- package/dist/chunk-VQ37VLAS.js +54 -0
- package/dist/chunk-VQ37VLAS.js.map +1 -0
- package/dist/chunk-VT7VSYH5.js +73 -0
- package/dist/chunk-VT7VSYH5.js.map +1 -0
- package/dist/chunk-VTIRUCLZ.js +57 -0
- package/dist/chunk-VTIRUCLZ.js.map +1 -0
- package/dist/chunk-VVBAEYKI.js +202 -0
- package/dist/chunk-VVBAEYKI.js.map +1 -0
- package/dist/chunk-WHFIQUCC.js +120 -0
- package/dist/chunk-WHFIQUCC.js.map +1 -0
- package/dist/chunk-WPSESV5Z.js +74 -0
- package/dist/chunk-WPSESV5Z.js.map +1 -0
- package/dist/chunk-WXEXCHEN.js +51 -0
- package/dist/chunk-WXEXCHEN.js.map +1 -0
- package/dist/chunk-X2DDPD3D.js +113 -0
- package/dist/chunk-X2DDPD3D.js.map +1 -0
- package/dist/chunk-X7VIMKLD.js +127 -0
- package/dist/chunk-X7VIMKLD.js.map +1 -0
- package/dist/chunk-XJ3EG6XY.js +30 -0
- package/dist/chunk-XJ3EG6XY.js.map +1 -0
- package/dist/chunk-XOT5HWSF.js +23 -0
- package/dist/chunk-XOT5HWSF.js.map +1 -0
- package/dist/chunk-Y72IP43U.js +117 -0
- package/dist/chunk-Y72IP43U.js.map +1 -0
- package/dist/chunk-YD6FLXBV.js +61 -0
- package/dist/chunk-YD6FLXBV.js.map +1 -0
- package/dist/chunk-YEQQGYYO.js +1022 -0
- package/dist/chunk-YEQQGYYO.js.map +1 -0
- package/dist/chunk-YYW6AEIT.js +46 -0
- package/dist/chunk-YYW6AEIT.js.map +1 -0
- package/dist/chunk-ZEVGXKRU.js +104 -0
- package/dist/chunk-ZEVGXKRU.js.map +1 -0
- package/dist/chunk-ZKSMMLDP.js +74 -0
- package/dist/chunk-ZKSMMLDP.js.map +1 -0
- package/dist/chunk-ZU6IM6PK.js +101 -0
- package/dist/chunk-ZU6IM6PK.js.map +1 -0
- package/dist/chunk-ZUS5KZGO.js +714 -0
- package/dist/chunk-ZUS5KZGO.js.map +1 -0
- package/dist/chunk-ZVS2GOT2.js +58 -0
- package/dist/chunk-ZVS2GOT2.js.map +1 -0
- package/dist/chunk-ZXPDS6DH.js +3 -0
- package/dist/chunk-ZXPDS6DH.js.map +1 -0
- package/dist/chunk-ZZQQJX5Z.js +173 -0
- package/dist/chunk-ZZQQJX5Z.js.map +1 -0
- package/dist/components.css +2 -0
- package/dist/composites/account-menu/index.js +6 -0
- package/dist/composites/account-menu/index.js.map +1 -0
- package/dist/composites/agent-composer/index.js +7 -0
- package/dist/composites/agent-composer/index.js.map +1 -0
- package/dist/composites/agent-editor/index.js +10 -0
- package/dist/composites/agent-editor/index.js.map +1 -0
- package/dist/composites/agent-stream/index.js +12 -0
- package/dist/composites/agent-stream/index.js.map +1 -0
- package/dist/composites/agent-timeline/index.js +5 -0
- package/dist/composites/agent-timeline/index.js.map +1 -0
- package/dist/composites/approval-card/index.js +5 -0
- package/dist/composites/approval-card/index.js.map +1 -0
- package/dist/composites/chat-composer/index.js +6 -0
- package/dist/composites/chat-composer/index.js.map +1 -0
- package/dist/composites/chat-message/index.js +6 -0
- package/dist/composites/chat-message/index.js.map +1 -0
- package/dist/composites/code-block/index.js +5 -0
- package/dist/composites/code-block/index.js.map +1 -0
- package/dist/composites/command-palette/index.js +5 -0
- package/dist/composites/command-palette/index.js.map +1 -0
- package/dist/composites/confirm-dialog/index.js +7 -0
- package/dist/composites/confirm-dialog/index.js.map +1 -0
- package/dist/composites/cron-jobs-list/index.js +5 -0
- package/dist/composites/cron-jobs-list/index.js.map +1 -0
- package/dist/composites/data-table/index.js +10 -0
- package/dist/composites/data-table/index.js.map +1 -0
- package/dist/composites/deployment-row/index.js +5 -0
- package/dist/composites/deployment-row/index.js.map +1 -0
- package/dist/composites/domain-config/index.js +7 -0
- package/dist/composites/domain-config/index.js.map +1 -0
- package/dist/composites/env-var-editor/index.js +7 -0
- package/dist/composites/env-var-editor/index.js.map +1 -0
- package/dist/composites/mcp-server-list/index.js +5 -0
- package/dist/composites/mcp-server-list/index.js.map +1 -0
- package/dist/composites/page-shell/index.js +7 -0
- package/dist/composites/page-shell/index.js.map +1 -0
- package/dist/composites/permission-modal/index.js +6 -0
- package/dist/composites/permission-modal/index.js.map +1 -0
- package/dist/composites/preview-env-card/index.js +6 -0
- package/dist/composites/preview-env-card/index.js.map +1 -0
- package/dist/composites/preview-panel/index.js +5 -0
- package/dist/composites/preview-panel/index.js.map +1 -0
- package/dist/composites/project-card/index.js +6 -0
- package/dist/composites/project-card/index.js.map +1 -0
- package/dist/composites/rollback-ui/index.js +6 -0
- package/dist/composites/rollback-ui/index.js.map +1 -0
- package/dist/composites/rule-editor/index.js +11 -0
- package/dist/composites/rule-editor/index.js.map +1 -0
- package/dist/composites/skill-editor/index.js +11 -0
- package/dist/composites/skill-editor/index.js.map +1 -0
- package/dist/composites/skills-list/index.js +5 -0
- package/dist/composites/skills-list/index.js.map +1 -0
- package/dist/composites/stability-bundle-viewer/index.js +4 -0
- package/dist/composites/stability-bundle-viewer/index.js.map +1 -0
- package/dist/composites/task-header/index.js +5 -0
- package/dist/composites/task-header/index.js.map +1 -0
- package/dist/composites/usage-meter/index.js +5 -0
- package/dist/composites/usage-meter/index.js.map +1 -0
- package/dist/fonts/LICENSE-GEIST.txt +92 -0
- package/dist/fonts/geist-400.woff2 +0 -0
- package/dist/fonts/geist-500.woff2 +0 -0
- package/dist/fonts/geist-600.woff2 +0 -0
- package/dist/fonts/geist-mono-400.woff2 +0 -0
- package/dist/fonts/geist-mono-500.woff2 +0 -0
- package/dist/fonts/geist-mono-600.woff2 +0 -0
- package/dist/fonts-cdn.css +28 -0
- package/dist/fonts.css +75 -0
- package/dist/index.d.ts +4621 -0
- package/dist/index.js +1338 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin-D5xmXqYb.d.ts +172 -0
- package/dist/preset-v3-legacy.d.ts +35 -0
- package/dist/preset-v3-legacy.js +159 -0
- package/dist/preset-v3-legacy.js.map +1 -0
- package/dist/preset.css +27 -0
- package/dist/primitives/action-bar/index.js +4 -0
- package/dist/primitives/action-bar/index.js.map +1 -0
- package/dist/primitives/agent-error-card/index.js +5 -0
- package/dist/primitives/agent-error-card/index.js.map +1 -0
- package/dist/primitives/agent-event/index.js +4 -0
- package/dist/primitives/agent-event/index.js.map +1 -0
- package/dist/primitives/agent-handoff/index.js +4 -0
- package/dist/primitives/agent-handoff/index.js.map +1 -0
- package/dist/primitives/agent-profile/index.js +4 -0
- package/dist/primitives/agent-profile/index.js.map +1 -0
- package/dist/primitives/agent-starting-state/index.js +5 -0
- package/dist/primitives/agent-starting-state/index.js.map +1 -0
- package/dist/primitives/agent-streaming/index.js +5 -0
- package/dist/primitives/agent-streaming/index.js.map +1 -0
- package/dist/primitives/alert/index.js +4 -0
- package/dist/primitives/alert/index.js.map +1 -0
- package/dist/primitives/artifact-preview/index.js +4 -0
- package/dist/primitives/artifact-preview/index.js.map +1 -0
- package/dist/primitives/attachment-chip/index.js +4 -0
- package/dist/primitives/attachment-chip/index.js.map +1 -0
- package/dist/primitives/audit-log-entry/index.js +4 -0
- package/dist/primitives/audit-log-entry/index.js.map +1 -0
- package/dist/primitives/auto-compact-notice/index.js +5 -0
- package/dist/primitives/auto-compact-notice/index.js.map +1 -0
- package/dist/primitives/avatar/index.js +4 -0
- package/dist/primitives/avatar/index.js.map +1 -0
- package/dist/primitives/badge/index.js +4 -0
- package/dist/primitives/badge/index.js.map +1 -0
- package/dist/primitives/branch-indicator/index.js +4 -0
- package/dist/primitives/branch-indicator/index.js.map +1 -0
- package/dist/primitives/browser-controls/index.js +4 -0
- package/dist/primitives/browser-controls/index.js.map +1 -0
- package/dist/primitives/build-log-stream/index.js +5 -0
- package/dist/primitives/build-log-stream/index.js.map +1 -0
- package/dist/primitives/button/index.js +4 -0
- package/dist/primitives/button/index.js.map +1 -0
- package/dist/primitives/capability-indicator/index.js +4 -0
- package/dist/primitives/capability-indicator/index.js.map +1 -0
- package/dist/primitives/card/index.js +4 -0
- package/dist/primitives/card/index.js.map +1 -0
- package/dist/primitives/channel-card/index.js +4 -0
- package/dist/primitives/channel-card/index.js.map +1 -0
- package/dist/primitives/chat-thread/index.js +5 -0
- package/dist/primitives/chat-thread/index.js.map +1 -0
- package/dist/primitives/checkbox/index.js +4 -0
- package/dist/primitives/checkbox/index.js.map +1 -0
- package/dist/primitives/context-card/index.js +4 -0
- package/dist/primitives/context-card/index.js.map +1 -0
- package/dist/primitives/context-window-bar/index.js +4 -0
- package/dist/primitives/context-window-bar/index.js.map +1 -0
- package/dist/primitives/copy-button/index.js +4 -0
- package/dist/primitives/copy-button/index.js.map +1 -0
- package/dist/primitives/cost-meter/index.js +4 -0
- package/dist/primitives/cost-meter/index.js.map +1 -0
- package/dist/primitives/created-files-card/index.js +4 -0
- package/dist/primitives/created-files-card/index.js.map +1 -0
- package/dist/primitives/cron-job-card/index.js +4 -0
- package/dist/primitives/cron-job-card/index.js.map +1 -0
- package/dist/primitives/danger-zone/index.js +4 -0
- package/dist/primitives/danger-zone/index.js.map +1 -0
- package/dist/primitives/dialog/index.js +4 -0
- package/dist/primitives/dialog/index.js.map +1 -0
- package/dist/primitives/diff-viewer/index.js +4 -0
- package/dist/primitives/diff-viewer/index.js.map +1 -0
- package/dist/primitives/dropdown-menu/index.js +4 -0
- package/dist/primitives/dropdown-menu/index.js.map +1 -0
- package/dist/primitives/empty-state/index.js +4 -0
- package/dist/primitives/empty-state/index.js.map +1 -0
- package/dist/primitives/export-chat-dialog/index.js +4 -0
- package/dist/primitives/export-chat-dialog/index.js.map +1 -0
- package/dist/primitives/folder-context-card/index.js +4 -0
- package/dist/primitives/folder-context-card/index.js.map +1 -0
- package/dist/primitives/folder-selector/index.js +4 -0
- package/dist/primitives/folder-selector/index.js.map +1 -0
- package/dist/primitives/form-field/index.js +4 -0
- package/dist/primitives/form-field/index.js.map +1 -0
- package/dist/primitives/gateway-status-indicator/index.js +4 -0
- package/dist/primitives/gateway-status-indicator/index.js.map +1 -0
- package/dist/primitives/hook-config/index.js +4 -0
- package/dist/primitives/hook-config/index.js.map +1 -0
- package/dist/primitives/hook-event-log/index.js +4 -0
- package/dist/primitives/hook-event-log/index.js.map +1 -0
- package/dist/primitives/input/index.js +4 -0
- package/dist/primitives/input/index.js.map +1 -0
- package/dist/primitives/intent-selector/index.js +4 -0
- package/dist/primitives/intent-selector/index.js.map +1 -0
- package/dist/primitives/label/index.js +4 -0
- package/dist/primitives/label/index.js.map +1 -0
- package/dist/primitives/lane-board/index.js +4 -0
- package/dist/primitives/lane-board/index.js.map +1 -0
- package/dist/primitives/login-split/index.js +4 -0
- package/dist/primitives/login-split/index.js.map +1 -0
- package/dist/primitives/mcp-server-card/index.js +4 -0
- package/dist/primitives/mcp-server-card/index.js.map +1 -0
- package/dist/primitives/memory-editor/index.js +4 -0
- package/dist/primitives/memory-editor/index.js.map +1 -0
- package/dist/primitives/mention-menu/index.js +4 -0
- package/dist/primitives/mention-menu/index.js.map +1 -0
- package/dist/primitives/metrics-panel/index.js +4 -0
- package/dist/primitives/metrics-panel/index.js.map +1 -0
- package/dist/primitives/model-card/index.js +4 -0
- package/dist/primitives/model-card/index.js.map +1 -0
- package/dist/primitives/model-selector/index.js +4 -0
- package/dist/primitives/model-selector/index.js.map +1 -0
- package/dist/primitives/pagination/index.js +4 -0
- package/dist/primitives/pagination/index.js.map +1 -0
- package/dist/primitives/permission-matrix/index.js +4 -0
- package/dist/primitives/permission-matrix/index.js.map +1 -0
- package/dist/primitives/pin-input/index.js +4 -0
- package/dist/primitives/pin-input/index.js.map +1 -0
- package/dist/primitives/plan-badge/index.js +4 -0
- package/dist/primitives/plan-badge/index.js.map +1 -0
- package/dist/primitives/progress/index.js +4 -0
- package/dist/primitives/progress/index.js.map +1 -0
- package/dist/primitives/progress-checklist/index.js +4 -0
- package/dist/primitives/progress-checklist/index.js.map +1 -0
- package/dist/primitives/project-switcher/index.js +4 -0
- package/dist/primitives/project-switcher/index.js.map +1 -0
- package/dist/primitives/quick-action-chips/index.js +4 -0
- package/dist/primitives/quick-action-chips/index.js.map +1 -0
- package/dist/primitives/radio-group/index.js +4 -0
- package/dist/primitives/radio-group/index.js.map +1 -0
- package/dist/primitives/recent-folders-list/index.js +4 -0
- package/dist/primitives/recent-folders-list/index.js.map +1 -0
- package/dist/primitives/rule-card/index.js +4 -0
- package/dist/primitives/rule-card/index.js.map +1 -0
- package/dist/primitives/run-stats/index.js +4 -0
- package/dist/primitives/run-stats/index.js.map +1 -0
- package/dist/primitives/run-status-pill/index.js +4 -0
- package/dist/primitives/run-status-pill/index.js.map +1 -0
- package/dist/primitives/running-tasks-panel/index.js +4 -0
- package/dist/primitives/running-tasks-panel/index.js.map +1 -0
- package/dist/primitives/scroll-area/index.js +4 -0
- package/dist/primitives/scroll-area/index.js.map +1 -0
- package/dist/primitives/select/index.js +4 -0
- package/dist/primitives/select/index.js.map +1 -0
- package/dist/primitives/session-list-item/index.js +4 -0
- package/dist/primitives/session-list-item/index.js.map +1 -0
- package/dist/primitives/session-timeline/index.js +4 -0
- package/dist/primitives/session-timeline/index.js.map +1 -0
- package/dist/primitives/sheet/index.js +4 -0
- package/dist/primitives/sheet/index.js.map +1 -0
- package/dist/primitives/sidebar/index.js +4 -0
- package/dist/primitives/sidebar/index.js.map +1 -0
- package/dist/primitives/skeleton/index.js +5 -0
- package/dist/primitives/skeleton/index.js.map +1 -0
- package/dist/primitives/skill-card/index.js +4 -0
- package/dist/primitives/skill-card/index.js.map +1 -0
- package/dist/primitives/social-auth-row/index.js +4 -0
- package/dist/primitives/social-auth-row/index.js.map +1 -0
- package/dist/primitives/stat-tile/index.js +4 -0
- package/dist/primitives/stat-tile/index.js.map +1 -0
- package/dist/primitives/status-dot/index.js +4 -0
- package/dist/primitives/status-dot/index.js.map +1 -0
- package/dist/primitives/steps-rail/index.js +4 -0
- package/dist/primitives/steps-rail/index.js.map +1 -0
- package/dist/primitives/sub-agent-dispatch/index.js +4 -0
- package/dist/primitives/sub-agent-dispatch/index.js.map +1 -0
- package/dist/primitives/switch/index.js +4 -0
- package/dist/primitives/switch/index.js.map +1 -0
- package/dist/primitives/system-prompt-editor/index.js +4 -0
- package/dist/primitives/system-prompt-editor/index.js.map +1 -0
- package/dist/primitives/table/index.js +4 -0
- package/dist/primitives/table/index.js.map +1 -0
- package/dist/primitives/tabs/index.js +4 -0
- package/dist/primitives/tabs/index.js.map +1 -0
- package/dist/primitives/task-plan/index.js +4 -0
- package/dist/primitives/task-plan/index.js.map +1 -0
- package/dist/primitives/terminal-panel/index.js +5 -0
- package/dist/primitives/terminal-panel/index.js.map +1 -0
- package/dist/primitives/textarea/index.js +4 -0
- package/dist/primitives/textarea/index.js.map +1 -0
- package/dist/primitives/thinking-level-selector/index.js +4 -0
- package/dist/primitives/thinking-level-selector/index.js.map +1 -0
- package/dist/primitives/timestamp/index.js +4 -0
- package/dist/primitives/timestamp/index.js.map +1 -0
- package/dist/primitives/toast/index.js +4 -0
- package/dist/primitives/toast/index.js.map +1 -0
- package/dist/primitives/token-usage-chart/index.js +4 -0
- package/dist/primitives/token-usage-chart/index.js.map +1 -0
- package/dist/primitives/tool-call/index.js +4 -0
- package/dist/primitives/tool-call/index.js.map +1 -0
- package/dist/primitives/tool-call-card/index.js +4 -0
- package/dist/primitives/tool-call-card/index.js.map +1 -0
- package/dist/primitives/tool-result/index.js +4 -0
- package/dist/primitives/tool-result/index.js.map +1 -0
- package/dist/primitives/tools-list/index.js +4 -0
- package/dist/primitives/tools-list/index.js.map +1 -0
- package/dist/primitives/tooltip/index.js +4 -0
- package/dist/primitives/tooltip/index.js.map +1 -0
- package/dist/primitives/topnav/index.js +4 -0
- package/dist/primitives/topnav/index.js.map +1 -0
- package/dist/primitives/update-banner/index.js +4 -0
- package/dist/primitives/update-banner/index.js.map +1 -0
- package/dist/slide/index.d.ts +212 -0
- package/dist/slide/index.js +3 -0
- package/dist/slide/index.js.map +1 -0
- package/dist/slide/plugins/emoji/index.d.ts +29 -0
- package/dist/slide/plugins/emoji/index.js +157 -0
- package/dist/slide/plugins/emoji/index.js.map +1 -0
- package/dist/slide/plugins/math/index.d.ts +13 -0
- package/dist/slide/plugins/math/index.js +145 -0
- package/dist/slide/plugins/math/index.js.map +1 -0
- package/dist/slide/plugins/mermaid/index.d.ts +55 -0
- package/dist/slide/plugins/mermaid/index.js +218 -0
- package/dist/slide/plugins/mermaid/index.js.map +1 -0
- package/dist/slide/plugins/shiki/index.d.ts +18 -0
- package/dist/slide/plugins/shiki/index.js +87 -0
- package/dist/slide/plugins/shiki/index.js.map +1 -0
- package/dist/slide/themes/default.css +256 -0
- package/dist/slide/themes/layouts.css +143 -0
- package/dist/slide/themes/violet-forge.css +256 -0
- package/dist/slide-deck/index.css +52 -0
- package/dist/slide-deck/index.css.map +1 -0
- package/dist/slide-deck/index.d.ts +377 -0
- package/dist/slide-deck/index.js +1111 -0
- package/dist/slide-deck/index.js.map +1 -0
- package/dist/styles-v3-legacy.css +88 -0
- package/dist/styles.css +137 -0
- package/dist/tokens-v4.css +187 -0
- package/dist/tokens.css +230 -0
- package/dist/vite-plugin.d.ts +29 -0
- package/dist/vite-plugin.js +76 -0
- package/dist/vite-plugin.js.map +1 -0
- package/dist/whiteboard/index.d.ts +258 -0
- package/dist/whiteboard/index.js +738 -0
- package/dist/whiteboard/index.js.map +1 -0
- package/llms.txt +273 -0
- package/package.json +800 -0
- package/registry/index.json +856 -0
- package/registry/r/account-menu.json +24 -0
- package/registry/r/action-bar.json +22 -0
- package/registry/r/agent-composer.json +22 -0
- package/registry/r/agent-editor.json +27 -0
- package/registry/r/agent-error-card.json +22 -0
- package/registry/r/agent-event.json +24 -0
- package/registry/r/agent-handoff.json +22 -0
- package/registry/r/agent-profile.json +23 -0
- package/registry/r/agent-starting-state.json +22 -0
- package/registry/r/agent-stream.json +27 -0
- package/registry/r/agent-streaming.json +22 -0
- package/registry/r/agent-timeline.json +22 -0
- package/registry/r/agent-types.json +15 -0
- package/registry/r/alert.json +22 -0
- package/registry/r/approval-card.json +25 -0
- package/registry/r/artifact-preview.json +22 -0
- package/registry/r/attachment-chip.json +24 -0
- package/registry/r/audit-log-entry.json +23 -0
- package/registry/r/auto-compact-notice.json +22 -0
- package/registry/r/avatar.json +23 -0
- package/registry/r/badge.json +22 -0
- package/registry/r/browser-controls.json +22 -0
- package/registry/r/build-log-stream.json +19 -0
- package/registry/r/button.json +23 -0
- package/registry/r/capability-indicator.json +23 -0
- package/registry/r/card.json +22 -0
- package/registry/r/chat-composer.json +23 -0
- package/registry/r/chat-message.json +129 -0
- package/registry/r/chat-thread.json +20 -0
- package/registry/r/chat-types.json +15 -0
- package/registry/r/checkbox.json +24 -0
- package/registry/r/cn.json +19 -0
- package/registry/r/code-block.json +21 -0
- package/registry/r/command-palette.json +25 -0
- package/registry/r/confirm-dialog.json +25 -0
- package/registry/r/context-card.json +23 -0
- package/registry/r/context-window-bar.json +20 -0
- package/registry/r/copy-button.json +22 -0
- package/registry/r/cost-meter.json +22 -0
- package/registry/r/created-files-card.json +23 -0
- package/registry/r/cron-job-card.json +22 -0
- package/registry/r/cron-jobs-list.json +23 -0
- package/registry/r/danger-zone.json +20 -0
- package/registry/r/data-table.json +27 -0
- package/registry/r/deployment-row.json +23 -0
- package/registry/r/dialog.json +23 -0
- package/registry/r/diff-viewer.json +20 -0
- package/registry/r/domain-config.json +25 -0
- package/registry/r/dropdown-menu.json +23 -0
- package/registry/r/empty-state.json +20 -0
- package/registry/r/env-var-editor.json +25 -0
- package/registry/r/folder-context-card.json +23 -0
- package/registry/r/folder-selector.json +22 -0
- package/registry/r/form-field.json +23 -0
- package/registry/r/hook-config.json +22 -0
- package/registry/r/hook-event-log.json +22 -0
- package/registry/r/input.json +22 -0
- package/registry/r/intent-selector.json +24 -0
- package/registry/r/label.json +22 -0
- package/registry/r/lane-board.json +20 -0
- package/registry/r/live-region-context.json +16 -0
- package/registry/r/login-split.json +20 -0
- package/registry/r/mcp-server-card.json +22 -0
- package/registry/r/mcp-server-list.json +23 -0
- package/registry/r/memory-editor.json +23 -0
- package/registry/r/mention-menu.json +23 -0
- package/registry/r/metrics-panel.json +22 -0
- package/registry/r/mode-types.json +15 -0
- package/registry/r/model-card.json +23 -0
- package/registry/r/model-selector.json +23 -0
- package/registry/r/page-shell.json +25 -0
- package/registry/r/pagination.json +22 -0
- package/registry/r/permission-matrix.json +22 -0
- package/registry/r/permission-modal.json +24 -0
- package/registry/r/permission-types.json +15 -0
- package/registry/r/pin-input.json +20 -0
- package/registry/r/plan-badge.json +20 -0
- package/registry/r/preview-env-card.json +25 -0
- package/registry/r/preview-panel.json +21 -0
- package/registry/r/progress-checklist.json +23 -0
- package/registry/r/progress.json +20 -0
- package/registry/r/project-card.json +25 -0
- package/registry/r/project-switcher.json +22 -0
- package/registry/r/quick-action-chips.json +21 -0
- package/registry/r/radio-group.json +23 -0
- package/registry/r/recent-folders-list.json +22 -0
- package/registry/r/rollback-ui.json +24 -0
- package/registry/r/rule-card.json +23 -0
- package/registry/r/rule-editor.json +28 -0
- package/registry/r/rule-types.json +18 -0
- package/registry/r/run-stats.json +22 -0
- package/registry/r/running-tasks-panel.json +22 -0
- package/registry/r/safe-href.json +16 -0
- package/registry/r/scroll-area.json +22 -0
- package/registry/r/select.json +24 -0
- package/registry/r/session-list-item.json +20 -0
- package/registry/r/session-timeline.json +22 -0
- package/registry/r/sheet.json +24 -0
- package/registry/r/sidebar.json +19 -0
- package/registry/r/skeleton.json +19 -0
- package/registry/r/skill-card.json +24 -0
- package/registry/r/skill-editor.json +28 -0
- package/registry/r/skills-list.json +23 -0
- package/registry/r/slide-deck.json +130 -0
- package/registry/r/slide-plugin-emoji.json +28 -0
- package/registry/r/slide-plugin-math.json +24 -0
- package/registry/r/slide-plugin-mermaid.json +23 -0
- package/registry/r/slide-plugin-shiki.json +23 -0
- package/registry/r/slide.json +123 -0
- package/registry/r/social-auth-row.json +21 -0
- package/registry/r/stat-tile.json +22 -0
- package/registry/r/status-dot.json +20 -0
- package/registry/r/steps-rail.json +20 -0
- package/registry/r/sub-agent-dispatch.json +22 -0
- package/registry/r/switch.json +23 -0
- package/registry/r/system-prompt-editor.json +22 -0
- package/registry/r/table.json +22 -0
- package/registry/r/tabs.json +22 -0
- package/registry/r/tailwind-preset.json +19 -0
- package/registry/r/task-header.json +24 -0
- package/registry/r/task-plan.json +22 -0
- package/registry/r/task-types.json +15 -0
- package/registry/r/terminal-panel.json +22 -0
- package/registry/r/textarea.json +22 -0
- package/registry/r/theme-provider.json +59 -0
- package/registry/r/theme-script.json +18 -0
- package/registry/r/theo-ui-provider.json +20 -0
- package/registry/r/timestamp.json +20 -0
- package/registry/r/toast.json +30 -0
- package/registry/r/token-usage-chart.json +20 -0
- package/registry/r/tokens.json +21 -0
- package/registry/r/tool-call-card.json +23 -0
- package/registry/r/tool-call.json +22 -0
- package/registry/r/tool-result.json +20 -0
- package/registry/r/tools-list.json +23 -0
- package/registry/r/tooltip.json +22 -0
- package/registry/r/topnav.json +22 -0
- package/registry/r/types.json +15 -0
- package/registry/r/usage-meter.json +21 -0
- package/registry/r/whiteboard.json +101 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/primitives/whiteboard/seed.ts","../../src/components/primitives/whiteboard/render/freedraw.tsx","../../src/components/primitives/whiteboard/render/rough-paths.ts","../../src/components/primitives/whiteboard/render/style.ts","../../src/components/primitives/whiteboard/render/line.tsx","../../src/components/primitives/whiteboard/render/shape.tsx","../../src/components/primitives/whiteboard/render/text.tsx","../../src/components/primitives/whiteboard/render/scene.tsx","../../src/components/primitives/whiteboard/schema.ts","../../src/components/primitives/whiteboard/validate.ts","../../src/components/primitives/whiteboard/viewport/use-pointer-pan.ts","../../src/components/primitives/whiteboard/viewport/use-viewport.ts","../../src/components/primitives/whiteboard/whiteboard.tsx"],"names":["strokeStyle","jsx","jsxs","align","fontFamily","z","useCallback","useMemo","useEffect","useRef"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Deterministic seed derivation for rough.js — see ADR D9.\n *\n * rough.js uses pseudo-randomness to produce the hand-drawn look. Without a\n * stable seed every render shifts the strokes slightly, breaking snapshot\n * tests, causing SSR hydration mismatches, and visible jitter when the parent\n * re-renders. FNV-1a 32-bit gives us a fast, dependency-free hash.\n */\n\nconst FNV_OFFSET_BASIS_32 = 0x811c9dc5;\nconst FNV_PRIME_32 = 0x01000193;\n\n/** FNV-1a 32-bit hash. Returns a signed 32-bit integer. */\nexport function fnv1a32(input: string): number {\n let hash = FNV_OFFSET_BASIS_32;\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i);\n // Multiply by the FNV prime, but keep within 32-bit unsigned range.\n hash = Math.imul(hash, FNV_PRIME_32);\n }\n // Cast to signed 32-bit via `| 0`.\n return hash | 0;\n}\n\ninterface SeedableShape {\n type: string;\n x: number;\n y: number;\n w?: number;\n h?: number;\n label?: string;\n seed?: number;\n}\n\n/** Return the element's explicit `seed` or derive a stable one from its props. */\nexport function deriveSeed(el: SeedableShape): number {\n if (typeof el.seed === \"number\" && Number.isFinite(el.seed)) {\n return el.seed | 0;\n }\n // Compose a key from the dimensions that visually define the shape. Other\n // fields (colors, opacity) don't change the underlying rough.js geometry.\n const key = `${el.type}|${el.x}|${el.y}|${el.w ?? \"\"}|${el.h ?? \"\"}|${el.label ?? \"\"}`;\n return fnv1a32(key);\n}\n","import { getStroke } from \"perfect-freehand\";\nimport type { FreedrawElement } from \"../schema.js\";\n\nconst DEFAULT_STROKE_OPTIONS = {\n size: 8,\n thinning: 0.5,\n smoothing: 0.5,\n streamline: 0.5,\n};\n\nfunction fmt(n: number | undefined): string {\n return typeof n === \"number\" && Number.isFinite(n) ? n.toFixed(2) : \"0\";\n}\n\nfunction svgPathFromStroke(points: number[][]): string {\n if (points.length === 0) return \"\";\n const first = points[0] ?? [];\n let d = `M ${fmt(first[0])} ${fmt(first[1])}`;\n for (let i = 1; i < points.length; i++) {\n const p = points[i] ?? [];\n d += ` L ${fmt(p[0])} ${fmt(p[1])}`;\n }\n d += \" Z\";\n return d;\n}\n\nexport function renderFreedraw(el: FreedrawElement): React.ReactNode {\n const size = (el.strokeWidth ?? 1.5) * 5;\n const inputPoints = el.points.map(([x, y, pressure]) => {\n const tx = el.x + x;\n const ty = el.y + y;\n return pressure === undefined ? [tx, ty] : [tx, ty, pressure];\n });\n const stroke = getStroke(inputPoints, {\n ...DEFAULT_STROKE_OPTIONS,\n size,\n });\n const d = svgPathFromStroke(stroke as number[][]);\n return (\n <g opacity={el.opacity ?? 1}>\n <path d={d} fill={el.stroke ?? \"currentColor\"} stroke=\"none\" />\n </g>\n );\n}\n","/**\n * Thin adapter over `roughjs` — converts a `Drawable` into the array of\n * `<path>` descriptors we render in SVG. The actual `rough.generator()`\n * instance is created once per scene and reused across elements.\n */\nimport type { Drawable, Options } from \"roughjs/bin/core.js\";\nimport type { RoughGenerator } from \"roughjs/bin/generator.js\";\n\nexport interface RoughPath {\n d: string;\n stroke: string;\n strokeWidth: number;\n fill?: string;\n}\n\nexport type RoughOptions = Options;\n\n/** Convert a rough.js Drawable into renderable SVG path descriptors. */\nexport function toRoughPaths(generator: RoughGenerator, drawable: Drawable): RoughPath[] {\n const paths = generator.toPaths(drawable);\n return paths.map((p) => ({\n d: p.d,\n stroke: p.stroke,\n strokeWidth: p.strokeWidth,\n fill: p.fill,\n }));\n}\n","/**\n * Maps a `WhiteboardElement` style props onto rough.js `Options`.\n */\nimport type { Options } from \"roughjs/bin/core.js\";\n\ninterface StyleSource {\n stroke?: string;\n strokeWidth?: number;\n strokeStyle?: \"solid\" | \"dashed\" | \"dotted\";\n fill?: string;\n fillStyle?: \"hachure\" | \"solid\" | \"cross-hatch\" | \"zigzag\";\n opacity?: number;\n roughness?: number;\n}\n\nconst DEFAULT_STROKE = \"currentColor\";\n\nexport function buildOptions(src: StyleSource, seed: number): Options {\n const o: Options = {\n seed,\n stroke: src.stroke ?? DEFAULT_STROKE,\n strokeWidth: src.strokeWidth ?? 1.5,\n roughness: src.roughness ?? 1.2,\n };\n if (src.strokeStyle === \"dashed\") o.strokeLineDash = [10, 6];\n else if (src.strokeStyle === \"dotted\") o.strokeLineDash = [2, 4];\n if (src.fill) o.fill = src.fill;\n if (src.fillStyle) o.fillStyle = src.fillStyle;\n return o;\n}\n\n/**\n * SVG `stroke-dasharray` value for a logical strokeStyle. rough.js's\n * `RoughGenerator.toPaths()` does NOT propagate `strokeLineDash` into the\n * returned `PathInfo` — only the canvas / direct-SVG backends apply it. We\n * must set the attribute ourselves on the rendered `<path>`. Returns\n * `undefined` for `solid` and any unknown value.\n */\nexport function strokeDashArray(\n strokeStyle: StyleSource[\"strokeStyle\"],\n strokeWidth: number,\n): string | undefined {\n if (strokeStyle === \"dashed\") {\n const dash = Math.max(8, strokeWidth * 6);\n const gap = Math.max(5, strokeWidth * 4);\n return `${dash} ${gap}`;\n }\n if (strokeStyle === \"dotted\") {\n // 1×strokeWidth dot, ~2×strokeWidth gap. Round end caps make these look\n // like dots instead of squares.\n return `${strokeWidth} ${strokeWidth * 2.5}`;\n }\n return undefined;\n}\n\nexport { DEFAULT_STROKE };\n","import type { RoughGenerator } from \"roughjs/bin/generator.js\";\nimport type { ArrowElement, LineElement } from \"../schema.js\";\nimport { toRoughPaths } from \"./rough-paths.js\";\nimport { buildOptions, strokeDashArray } from \"./style.js\";\n\nconst HEAD_BASE_PX = 12;\nconst HEAD_ANGLE_RAD = Math.PI / 7; // ~25°\n\ninterface HeadGeom {\n apexX: number;\n apexY: number;\n leftX: number;\n leftY: number;\n rightX: number;\n rightY: number;\n}\n\nfunction arrowHeadGeometry(\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n strokeWidth: number,\n): HeadGeom | null {\n const dx = toX - fromX;\n const dy = toY - fromY;\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist === 0) return null;\n const angle = Math.atan2(dy, dx);\n // EC-7: clamp head length so it never exceeds 40% of the segment.\n const headLen = Math.min(HEAD_BASE_PX + strokeWidth * 2, dist * 0.4);\n const leftX = toX - headLen * Math.cos(angle - HEAD_ANGLE_RAD);\n const leftY = toY - headLen * Math.sin(angle - HEAD_ANGLE_RAD);\n const rightX = toX - headLen * Math.cos(angle + HEAD_ANGLE_RAD);\n const rightY = toY - headLen * Math.sin(angle + HEAD_ANGLE_RAD);\n return { apexX: toX, apexY: toY, leftX, leftY, rightX, rightY };\n}\n\nfunction lineBody(\n gen: RoughGenerator,\n el: LineElement | ArrowElement,\n seed: number,\n): React.ReactNode[] {\n const opts = buildOptions(el, seed);\n const drawable = gen.line(el.x, el.y, el.to[0], el.to[1], opts);\n const dash = strokeDashArray(el.strokeStyle, el.strokeWidth ?? 1.5);\n return toRoughPaths(gen, drawable).map((p, i) => (\n <path\n // biome-ignore lint/suspicious/noArrayIndexKey: stable rough.js path order\n key={`body-${i}`}\n d={p.d}\n stroke={p.stroke}\n strokeWidth={p.strokeWidth}\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={dash}\n />\n ));\n}\n\nfunction arrowHead(\n gen: RoughGenerator,\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n seed: number,\n el: ArrowElement,\n side: \"start\" | \"end\",\n): React.ReactNode[] {\n const geom = arrowHeadGeometry(fromX, fromY, toX, toY, el.strokeWidth ?? 1.5);\n if (!geom) return [];\n const opts = buildOptions(el, seed);\n // Two short rough-drawn segments forming the V.\n const leftDrawable = gen.line(geom.apexX, geom.apexY, geom.leftX, geom.leftY, opts);\n const rightDrawable = gen.line(geom.apexX, geom.apexY, geom.rightX, geom.rightY, opts);\n const leftPaths = toRoughPaths(gen, leftDrawable);\n const rightPaths = toRoughPaths(gen, rightDrawable);\n const nodes: React.ReactNode[] = [];\n for (const [i, p] of leftPaths.entries()) {\n nodes.push(\n <path\n key={`${side}-l-${i}`}\n d={p.d}\n stroke={p.stroke}\n strokeWidth={p.strokeWidth}\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n data-line-part=\"arrowhead\"\n />,\n );\n }\n for (const [i, p] of rightPaths.entries()) {\n nodes.push(\n <path\n key={`${side}-r-${i}`}\n d={p.d}\n stroke={p.stroke}\n strokeWidth={p.strokeWidth}\n fill=\"none\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n data-line-part=\"arrowhead\"\n />,\n );\n }\n return nodes;\n}\n\nexport function renderLine(gen: RoughGenerator, el: LineElement): React.ReactNode {\n return <g opacity={el.opacity ?? 1}>{lineBody(gen, el, el.seed ?? 0)}</g>;\n}\n\nexport function renderArrow(gen: RoughGenerator, el: ArrowElement): React.ReactNode {\n const seed = el.seed ?? 0;\n const nodes: React.ReactNode[] = [...lineBody(gen, el, seed)];\n if (el.headEnd !== false) {\n nodes.push(...arrowHead(gen, el.x, el.y, el.to[0], el.to[1], seed + 1, el, \"end\"));\n }\n if (el.headStart) {\n nodes.push(...arrowHead(gen, el.to[0], el.to[1], el.x, el.y, seed + 2, el, \"start\"));\n }\n let label: React.ReactNode = null;\n if (el.label) {\n const midX = (el.x + el.to[0]) / 2;\n const midY = (el.y + el.to[1]) / 2;\n // Offset perpendicular to the line so label doesn't sit on the stroke.\n const dx = el.to[0] - el.x;\n const dy = el.to[1] - el.y;\n const dist = Math.sqrt(dx * dx + dy * dy) || 1;\n const nx = -dy / dist;\n const ny = dx / dist;\n const offset = 12;\n label = (\n <text\n x={midX + nx * offset}\n y={midY + ny * offset}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fontSize={14}\n fontFamily=\"ui-sans-serif, system-ui, sans-serif\"\n fill={el.stroke ?? \"currentColor\"}\n style={{ pointerEvents: \"none\" }}\n >\n {el.label}\n </text>\n );\n }\n return (\n <g opacity={el.opacity ?? 1}>\n {nodes}\n {label}\n </g>\n );\n}\n","import type { RoughGenerator } from \"roughjs/bin/generator.js\";\nimport type { DiamondElement, EllipseElement, RectElement } from \"../schema.js\";\nimport { toRoughPaths } from \"./rough-paths.js\";\nimport { buildOptions, strokeDashArray } from \"./style.js\";\n\ninterface LabelProps {\n cx: number;\n cy: number;\n label: string;\n stroke?: string;\n}\n\nfunction Label({ cx, cy, label, stroke }: LabelProps) {\n return (\n <text\n x={cx}\n y={cy}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fontSize={16}\n fontFamily=\"ui-sans-serif, system-ui, sans-serif\"\n fill={stroke ?? \"currentColor\"}\n style={{ pointerEvents: \"none\" }}\n >\n {label}\n </text>\n );\n}\n\nfunction pathsToReactNodes(\n paths: ReturnType<typeof toRoughPaths>,\n keyPrefix: string,\n outlineStroke: string,\n dashArray?: string,\n): React.ReactNode[] {\n return paths.map((p, i) => {\n // Apply stroke-dasharray only to paths whose stroke matches the outline\n // color — this avoids dashing hachure/cross-hatch fill lines (which are\n // stroked in the fill color, not the outline color) when a shape mixes\n // fillStyle with strokeStyle.\n const isOutline = p.stroke === outlineStroke;\n return (\n <path\n // biome-ignore lint/suspicious/noArrayIndexKey: rough.js path order is stable for a given (geometry, seed) tuple — index is the most precise key.\n key={`${keyPrefix}-${i}`}\n d={p.d}\n stroke={p.stroke}\n strokeWidth={p.strokeWidth}\n fill={p.fill ?? \"none\"}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={isOutline ? dashArray : undefined}\n />\n );\n });\n}\n\nexport function renderRect(gen: RoughGenerator, el: RectElement): React.ReactNode {\n const opts = buildOptions(el, el.seed ?? 0);\n const drawable = gen.rectangle(el.x, el.y, el.w, el.h, opts);\n const paths = toRoughPaths(gen, drawable);\n const dash = strokeDashArray(el.strokeStyle, el.strokeWidth ?? 1.5);\n return (\n <g opacity={el.opacity ?? 1}>\n {pathsToReactNodes(paths, \"rect\", opts.stroke as string, dash)}\n {el.label ? (\n <Label cx={el.x + el.w / 2} cy={el.y + el.h / 2} label={el.label} stroke={el.stroke} />\n ) : null}\n </g>\n );\n}\n\nexport function renderEllipse(gen: RoughGenerator, el: EllipseElement): React.ReactNode {\n const opts = buildOptions(el, el.seed ?? 0);\n // rough.js ellipse takes center + width + height.\n const drawable = gen.ellipse(el.x + el.w / 2, el.y + el.h / 2, el.w, el.h, opts);\n const paths = toRoughPaths(gen, drawable);\n const dash = strokeDashArray(el.strokeStyle, el.strokeWidth ?? 1.5);\n return (\n <g opacity={el.opacity ?? 1}>\n {pathsToReactNodes(paths, \"ellipse\", opts.stroke as string, dash)}\n {el.label ? (\n <Label cx={el.x + el.w / 2} cy={el.y + el.h / 2} label={el.label} stroke={el.stroke} />\n ) : null}\n </g>\n );\n}\n\nexport function renderDiamond(gen: RoughGenerator, el: DiamondElement): React.ReactNode {\n const opts = buildOptions(el, el.seed ?? 0);\n const cx = el.x + el.w / 2;\n const cy = el.y + el.h / 2;\n const points: [number, number][] = [\n [cx, el.y], // top\n [el.x + el.w, cy], // right\n [cx, el.y + el.h], // bottom\n [el.x, cy], // left\n ];\n const drawable = gen.polygon(points, opts);\n const paths = toRoughPaths(gen, drawable);\n const dash = strokeDashArray(el.strokeStyle, el.strokeWidth ?? 1.5);\n return (\n <g opacity={el.opacity ?? 1}>\n {pathsToReactNodes(paths, \"diamond\", opts.stroke as string, dash)}\n {el.label ? <Label cx={cx} cy={cy} label={el.label} stroke={el.stroke} /> : null}\n </g>\n );\n}\n","import type { TextElement } from \"../schema.js\";\n\nconst FONT_STACKS: Record<NonNullable<TextElement[\"fontFamily\"]>, string> = {\n sans: \"ui-sans-serif, system-ui, sans-serif\",\n serif: \"ui-serif, Georgia, serif\",\n mono: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n hand: '\"Virgil\", \"Caveat\", \"Comic Sans MS\", cursive',\n};\n\nfunction textAnchor(align: TextElement[\"align\"]): \"start\" | \"middle\" | \"end\" {\n if (align === \"center\") return \"middle\";\n if (align === \"right\") return \"end\";\n return \"start\";\n}\n\nexport function renderText(el: TextElement): React.ReactNode {\n const fontSize = el.fontSize ?? 18;\n const fontFamily = FONT_STACKS[el.fontFamily ?? \"hand\"];\n const anchor = textAnchor(el.align);\n const lines = el.text.split(\"\\n\");\n // dy: first tspan at 0, subsequent at fontSize * 1.2 line-height.\n return (\n <g opacity={el.opacity ?? 1}>\n <text\n x={el.x}\n y={el.y}\n textAnchor={anchor}\n dominantBaseline=\"hanging\"\n fontSize={fontSize}\n fontFamily={fontFamily}\n fill={el.stroke ?? \"currentColor\"}\n >\n {lines.map((line, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: text is split deterministically on '\\n' so the line index is the most stable key.\n <tspan key={i} x={el.x} dy={i === 0 ? 0 : fontSize * 1.2}>\n {line}\n </tspan>\n ))}\n </text>\n </g>\n );\n}\n","import type { RoughGenerator } from \"roughjs/bin/generator.js\";\nimport type { WhiteboardElement, WhiteboardScene } from \"../schema.js\";\nimport { deriveSeed } from \"../seed.js\";\nimport { renderFreedraw } from \"./freedraw.js\";\nimport { renderArrow, renderLine } from \"./line.js\";\nimport { renderDiamond, renderEllipse, renderRect } from \"./shape.js\";\nimport { renderText } from \"./text.js\";\n\nfunction elementWithSeed<T extends WhiteboardElement>(el: T): T {\n if (typeof el.seed === \"number\") return el;\n return { ...el, seed: deriveSeed(el) } as T;\n}\n\nfunction renderElement(el: WhiteboardElement, gen: RoughGenerator): React.ReactNode {\n switch (el.type) {\n case \"rect\":\n return renderRect(gen, elementWithSeed(el));\n case \"ellipse\":\n return renderEllipse(gen, elementWithSeed(el));\n case \"diamond\":\n return renderDiamond(gen, elementWithSeed(el));\n case \"line\":\n return renderLine(gen, elementWithSeed(el));\n case \"arrow\":\n return renderArrow(gen, elementWithSeed(el));\n case \"text\":\n return renderText(elementWithSeed(el));\n case \"freedraw\":\n return renderFreedraw(elementWithSeed(el));\n }\n}\n\nexport function renderScene(scene: WhiteboardScene, gen: RoughGenerator): React.ReactNode {\n return (\n <>\n {scene.elements.map((el, i) => (\n <g\n key={el.id ?? `__idx-${i}`}\n data-element-id={el.id ?? String(i)}\n data-element-type={el.type}\n >\n {renderElement(el, gen)}\n </g>\n ))}\n </>\n );\n}\n","/**\n * Zod schema for the Whiteboard JSON v1 (`WhiteboardScene`).\n *\n * Design goals (see RFC 0001 §4 and ADR D4 in the plan):\n * - LLM-friendly: minimal fields per element.\n * - Discriminated union by `type` for exhaustive typing in TS.\n * - Defensive against LLM mistakes:\n * - EC-3: `.finite()` everywhere — rejects NaN / Infinity.\n * - EC-4: `.max()` on dimensions to cap absurd values from the model.\n */\nimport { z } from \"zod\";\n\nconst finiteNumber = z.number().finite();\nconst finitePositive = finiteNumber.positive();\n\nconst strokeStyle = z.enum([\"solid\", \"dashed\", \"dotted\"]);\nconst fillStyle = z.enum([\"hachure\", \"solid\", \"cross-hatch\", \"zigzag\"]);\nconst align = z.enum([\"left\", \"center\", \"right\"]);\nconst fontFamily = z.enum([\"sans\", \"serif\", \"mono\", \"hand\"]);\nconst roundness = z.enum([\"sharp\", \"round\"]);\n\nconst baseElement = z.object({\n id: z.string().max(120).optional(),\n x: finiteNumber,\n y: finiteNumber,\n stroke: z.string().max(64).optional(),\n strokeWidth: finitePositive.max(50).optional(),\n strokeStyle: strokeStyle.optional(),\n fill: z.string().max(64).optional(),\n fillStyle: fillStyle.optional(),\n opacity: finiteNumber.min(0).max(1).optional(),\n roughness: finiteNumber.min(0).max(3).optional(),\n seed: z.number().int().finite().optional(),\n});\n\nconst dim = finitePositive.max(20000);\nconst labelText = z.string().max(500);\n\nconst rectElement = baseElement.extend({\n type: z.literal(\"rect\"),\n w: dim,\n h: dim,\n label: labelText.optional(),\n roundness: roundness.optional(),\n});\n\nconst ellipseElement = baseElement.extend({\n type: z.literal(\"ellipse\"),\n w: dim,\n h: dim,\n label: labelText.optional(),\n});\n\nconst diamondElement = baseElement.extend({\n type: z.literal(\"diamond\"),\n w: dim,\n h: dim,\n label: labelText.optional(),\n});\n\nconst point2 = z.tuple([finiteNumber, finiteNumber]);\n\nconst lineElement = baseElement.extend({\n type: z.literal(\"line\"),\n to: point2,\n});\n\nconst arrowElement = baseElement.extend({\n type: z.literal(\"arrow\"),\n to: point2,\n label: labelText.optional(),\n headStart: z.boolean().optional(),\n headEnd: z.boolean().default(true),\n});\n\nconst textElement = baseElement.extend({\n type: z.literal(\"text\"),\n text: z.string().max(5000),\n fontSize: finitePositive.max(500).optional(),\n align: align.optional(),\n fontFamily: fontFamily.optional(),\n});\n\nconst freedrawPoint = z.tuple([finiteNumber, finiteNumber, finiteNumber.optional()]);\n\nconst freedrawElement = baseElement.extend({\n type: z.literal(\"freedraw\"),\n points: z.array(freedrawPoint).min(2).max(5000),\n});\n\nexport const whiteboardElement = z.discriminatedUnion(\"type\", [\n rectElement,\n ellipseElement,\n diamondElement,\n lineElement,\n arrowElement,\n textElement,\n freedrawElement,\n]);\n\nexport const whiteboardScene = z.object({\n version: z.literal(1),\n width: dim, // EC-4: clamped 1..20000\n height: dim, // EC-4: clamped 1..20000\n background: z.string().max(64).optional(),\n elements: z.array(whiteboardElement).max(5000),\n});\n\n// Internal \"parsed\" types (defaults applied) — used inside the renderer.\nexport type WhiteboardElement = z.output<typeof whiteboardElement>;\nexport type WhiteboardScene = z.output<typeof whiteboardScene>;\nexport type RectElement = z.output<typeof rectElement>;\nexport type EllipseElement = z.output<typeof ellipseElement>;\nexport type DiamondElement = z.output<typeof diamondElement>;\nexport type LineElement = z.output<typeof lineElement>;\nexport type ArrowElement = z.output<typeof arrowElement>;\nexport type TextElement = z.output<typeof textElement>;\nexport type FreedrawElement = z.output<typeof freedrawElement>;\n\n// Public \"input\" types (defaults optional) — used by consumers passing data.\nexport type WhiteboardElementInput = z.input<typeof whiteboardElement>;\nexport type WhiteboardSceneInput = z.input<typeof whiteboardScene>;\n","/**\n * Public validator for `WhiteboardScene` JSON. Wraps Zod and converts errors\n * into a structured shape that an LLM can consume to self-correct.\n *\n * Returns `{ ok: true, scene }` on success or `{ ok: false, errors }` with\n * each error carrying `{ path, message, code, got? }`. See RFC 0001 §4.\n */\nimport { type WhiteboardScene, whiteboardScene } from \"./schema.js\";\n\nexport interface ValidationError {\n /** Dot-joined Zod path, e.g. \"elements.2.type\" or \"width\". */\n path: string;\n /** Human-readable explanation (passes through Zod's message). */\n message: string;\n /** Zod issue code: `invalid_type`, `too_small`, `invalid_literal`, ... */\n code: string;\n /** Actual value received at `path`. Populated for type mismatches, discriminator mismatches, and any issue where Zod's `received` is absent but the value can be recovered by walking the original input along `path`. */\n got?: unknown;\n}\n\nexport type ValidationResult =\n | { ok: true; scene: WhiteboardScene }\n | { ok: false; errors: ValidationError[] };\n\ninterface ZodLikeIssue {\n path: ReadonlyArray<string | number>;\n message: string;\n code: string;\n received?: unknown;\n}\n\n/** Walk `input` following the issue path and return the offending value. */\nfunction valueAtPath(input: unknown, path: ReadonlyArray<string | number>): unknown {\n let cursor: unknown = input;\n for (const segment of path) {\n if (cursor === null || typeof cursor !== \"object\") return undefined;\n cursor = (cursor as Record<string | number, unknown>)[segment];\n }\n return cursor;\n}\n\nfunction formatIssue(issue: ZodLikeIssue, input: unknown): ValidationError {\n const error: ValidationError = {\n path: issue.path.join(\".\"),\n message: issue.message,\n code: issue.code,\n };\n // Populate `got` from the issue when Zod provides it (invalid_type), or by\n // walking the original input along the path (invalid_union / invalid_value).\n // LLM auto-correction benefits from seeing what was actually emitted.\n if (\"received\" in issue && issue.received !== undefined) {\n error.got = issue.received;\n } else if (issue.path.length > 0) {\n const value = valueAtPath(input, issue.path);\n if (value !== undefined) error.got = value;\n }\n return error;\n}\n\nexport function validateScene(input: unknown): ValidationResult {\n const result = whiteboardScene.safeParse(input);\n if (result.success) {\n return { ok: true, scene: result.data };\n }\n const errors = result.error.issues.map((issue) =>\n formatIssue(issue as unknown as ZodLikeIssue, input),\n );\n return { ok: false, errors };\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport type { ViewportControls } from \"./use-viewport.js\";\n\ninterface DragState {\n pointerId: number;\n lastX: number;\n lastY: number;\n}\n\n/** Attaches pan + zoom listeners to an SVG element. */\nexport function usePointerPan(\n ref: React.RefObject<SVGSVGElement | null>,\n viewport: ViewportControls,\n size: { width: number; height: number },\n): {\n onPointerDown: (e: React.PointerEvent<SVGSVGElement>) => void;\n onPointerMove: (e: React.PointerEvent<SVGSVGElement>) => void;\n onPointerUp: (e: React.PointerEvent<SVGSVGElement>) => void;\n onPointerCancel: (e: React.PointerEvent<SVGSVGElement>) => void;\n} {\n const dragRef = useRef<DragState | null>(null);\n const spaceHeldRef = useRef(false);\n\n // EC-2: wheel events on React's JSX onWheel are passive — `preventDefault`\n // does nothing, which causes the page to scroll while the user tries to\n // zoom. We must attach the wheel handler imperatively with `{passive:false}`.\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const handler = (e: WheelEvent) => {\n e.preventDefault();\n const rect = el.getBoundingClientRect();\n const localX = e.clientX - rect.left;\n const localY = e.clientY - rect.top;\n // Map screen-px → viewBox coords by ratio of rect to size.\n const scaleX = size.width / rect.width;\n const scaleY = size.height / rect.height;\n viewport.zoomAt(localX * scaleX, localY * scaleY, -e.deltaY * 0.001, size);\n };\n el.addEventListener(\"wheel\", handler, { passive: false });\n return () => el.removeEventListener(\"wheel\", handler);\n }, [ref, viewport, size]);\n\n // Track Space key for pan-with-any-button (Excalidraw \"hand\" mode).\n useEffect(() => {\n const down = (e: KeyboardEvent) => {\n if (e.code === \"Space\") spaceHeldRef.current = true;\n };\n const up = (e: KeyboardEvent) => {\n if (e.code === \"Space\") spaceHeldRef.current = false;\n };\n window.addEventListener(\"keydown\", down);\n window.addEventListener(\"keyup\", up);\n return () => {\n window.removeEventListener(\"keydown\", down);\n window.removeEventListener(\"keyup\", up);\n };\n }, []);\n\n const onPointerDown = useCallback((e: React.PointerEvent<SVGSVGElement>) => {\n // EC-10: only start drag when the down event is on our SVG, not on a\n // child rendered via portal/etc. event.currentTarget guarantees this.\n if (e.target instanceof Element && !e.currentTarget.contains(e.target)) return;\n // Left button (0) or middle (1) or Space-held pan.\n const isMouseButton = e.button === 0 || e.button === 1;\n if (!isMouseButton && e.pointerType === \"mouse\") return;\n if (e.pointerType === \"mouse\" && e.button !== 1 && !spaceHeldRef.current && e.button !== 0) {\n return;\n }\n dragRef.current = { pointerId: e.pointerId, lastX: e.clientX, lastY: e.clientY };\n e.currentTarget.setPointerCapture(e.pointerId);\n }, []);\n\n const onPointerMove = useCallback(\n (e: React.PointerEvent<SVGSVGElement>) => {\n const drag = dragRef.current;\n if (!drag || drag.pointerId !== e.pointerId) return;\n const dx = e.clientX - drag.lastX;\n const dy = e.clientY - drag.lastY;\n drag.lastX = e.clientX;\n drag.lastY = e.clientY;\n const el = ref.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const scaleX = size.width / rect.width;\n const scaleY = size.height / rect.height;\n viewport.pan(dx * scaleX, dy * scaleY);\n },\n [ref, viewport, size],\n );\n\n const releaseDrag = useCallback((e: React.PointerEvent<SVGSVGElement>) => {\n const drag = dragRef.current;\n if (!drag || drag.pointerId !== e.pointerId) return;\n try {\n e.currentTarget.releasePointerCapture(e.pointerId);\n } catch {\n // Already released — ignore.\n }\n dragRef.current = null;\n }, []);\n\n return {\n onPointerDown,\n onPointerMove,\n onPointerUp: releaseDrag,\n onPointerCancel: releaseDrag,\n };\n}\n","/**\n * Viewport state and helpers — pan via (x, y) and zoom via a scalar.\n *\n * Coordinate system:\n * - World space: where elements are defined (the JSON `x`, `y` etc.).\n * - Screen space: the rendered SVG bounding box on the page.\n * - viewBox: `${x} ${y} ${width/zoom} ${height/zoom}`. Increasing zoom\n * SHRINKS the viewBox dimensions, magnifying the rendered content.\n *\n * `zoomAt(screenX, screenY, delta, viewportSize)` keeps the world point under\n * the cursor stable while zooming (see test for invariant).\n */\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport const MIN_ZOOM = 0.1;\nexport const MAX_ZOOM = 8;\n\nexport interface ViewportState {\n x: number;\n y: number;\n zoom: number;\n}\n\nexport interface ViewportSize {\n width: number;\n height: number;\n}\n\nexport interface ViewportBounds {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport interface UseViewportOptions {\n width: number;\n height: number;\n initialZoom?: number;\n initialCenter?: [number, number];\n}\n\nexport interface ViewportControls {\n state: ViewportState;\n pan: (dx: number, dy: number) => void;\n setZoom: (zoom: number) => void;\n zoomAt: (screenX: number, screenY: number, delta: number, size: ViewportSize) => void;\n reset: () => void;\n fitTo: (bounds: ViewportBounds, size: ViewportSize) => void;\n viewBox: (size: ViewportSize) => string;\n}\n\nfunction clampZoom(z: number): number {\n if (!Number.isFinite(z)) return 1;\n return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, z));\n}\n\nexport function useViewport(opts: UseViewportOptions): ViewportControls {\n const initial: ViewportState = useMemo(() => {\n const zoom = clampZoom(opts.initialZoom ?? 1);\n if (opts.initialCenter) {\n // Position viewBox so initialCenter sits at the visual center.\n const [cx, cy] = opts.initialCenter;\n return {\n x: cx - opts.width / (2 * zoom),\n y: cy - opts.height / (2 * zoom),\n zoom,\n };\n }\n return { x: 0, y: 0, zoom };\n }, [opts.initialCenter, opts.initialZoom, opts.width, opts.height]);\n\n const [state, setState] = useState<ViewportState>(initial);\n\n const pan = useCallback((dx: number, dy: number) => {\n setState((prev) => ({ ...prev, x: prev.x - dx / prev.zoom, y: prev.y - dy / prev.zoom }));\n }, []);\n\n const setZoom = useCallback((zoom: number) => {\n setState((prev) => ({ ...prev, zoom: clampZoom(zoom) }));\n }, []);\n\n const zoomAt = useCallback(\n (screenX: number, screenY: number, delta: number, _size: ViewportSize) => {\n setState((prev) => {\n const oldZoom = prev.zoom;\n const newZoom = clampZoom(prev.zoom * Math.exp(delta));\n if (newZoom === oldZoom) return prev;\n // World coordinate currently under cursor.\n const worldX = prev.x + screenX / oldZoom;\n const worldY = prev.y + screenY / oldZoom;\n // After zoom, we want the same screen point to map to the same world point.\n // viewBox.x + (screenX / newZoom) === worldX → x = worldX - screenX/newZoom.\n return {\n x: worldX - screenX / newZoom,\n y: worldY - screenY / newZoom,\n zoom: newZoom,\n };\n });\n },\n [],\n );\n\n const reset = useCallback(() => setState(initial), [initial]);\n\n const fitTo = useCallback((bounds: ViewportBounds, size: ViewportSize) => {\n const bboxWidth = Math.max(1, bounds.maxX - bounds.minX);\n const bboxHeight = Math.max(1, bounds.maxY - bounds.minY);\n const zoomX = size.width / bboxWidth;\n const zoomY = size.height / bboxHeight;\n const zoom = clampZoom(Math.min(zoomX, zoomY));\n const cx = (bounds.minX + bounds.maxX) / 2;\n const cy = (bounds.minY + bounds.maxY) / 2;\n setState({\n x: cx - size.width / (2 * zoom),\n y: cy - size.height / (2 * zoom),\n zoom,\n });\n }, []);\n\n const viewBox = useCallback(\n (size: ViewportSize) =>\n `${state.x} ${state.y} ${size.width / state.zoom} ${size.height / state.zoom}`,\n [state],\n );\n\n return { state, pan, setZoom, zoomAt, reset, fitTo, viewBox };\n}\n","import { useEffect, useMemo, useRef } from \"react\";\n/**\n * `<Whiteboard>` — view-only primitive that turns a JSON scene into a\n * hand-drawn SVG. Lives in the isolated subpath `@theokit/ui/whiteboard`.\n *\n * See RFC 0001 (`docs/rfcs/0001-whiteboard.md`) and the plan in\n * `.claude/knowledge-base/plans/whiteboard-view-primitive-plan.md`.\n */\nimport rough from \"roughjs\";\nimport type { RoughGenerator } from \"roughjs/bin/generator.js\";\nimport { renderScene } from \"./render/scene.js\";\nimport type { WhiteboardScene, WhiteboardSceneInput } from \"./schema.js\";\nimport { type ValidationError, validateScene } from \"./validate.js\";\nimport { usePointerPan } from \"./viewport/use-pointer-pan.js\";\nimport { useViewport } from \"./viewport/use-viewport.js\";\n\n/** Input type accepted by the component (defaults like `headEnd` are optional). */\nexport type WhiteboardData = WhiteboardSceneInput;\nexport type { ValidationError } from \"./validate.js\";\n\nexport interface WhiteboardProps {\n /** The scene to render. Validated with Zod on every change. */\n data: WhiteboardData | unknown;\n className?: string;\n /** Starting zoom level (clamped 0.1–8). Default 1. */\n initialZoom?: number;\n /** World coordinate centered in the viewport on first render. */\n initialCenter?: [number, number];\n /** When true, computes a bounding box of all elements and zooms to fit. */\n fitOnLoad?: boolean;\n /** Called once per validation failure with the list of errors (EC-6: in useEffect, not render). */\n onValidationError?: (errors: ValidationError[]) => void;\n /** Accessible label for the SVG (defaults to \"Whiteboard diagram\"). */\n \"aria-label\"?: string;\n}\n\nfunction computeBounds(scene: WhiteboardScene): {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n} | null {\n if (scene.elements.length === 0) return null;\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (const el of scene.elements) {\n const x1 = el.x;\n const y1 = el.y;\n let x2 = el.x;\n let y2 = el.y;\n if (el.type === \"rect\" || el.type === \"ellipse\" || el.type === \"diamond\") {\n x2 = el.x + el.w;\n y2 = el.y + el.h;\n } else if (el.type === \"line\" || el.type === \"arrow\") {\n x2 = el.to[0];\n y2 = el.to[1];\n } else if (el.type === \"freedraw\") {\n for (const [px, py] of el.points) {\n const tx = el.x + px;\n const ty = el.y + py;\n if (tx < minX) minX = tx;\n if (ty < minY) minY = ty;\n if (tx > maxX) maxX = tx;\n if (ty > maxY) maxY = ty;\n }\n continue;\n }\n if (x1 < minX) minX = x1;\n if (y1 < minY) minY = y1;\n if (x2 < minX) minX = x2;\n if (y2 < minY) minY = y2;\n if (x1 > maxX) maxX = x1;\n if (y1 > maxY) maxY = y1;\n if (x2 > maxX) maxX = x2;\n if (y2 > maxY) maxY = y2;\n }\n if (!Number.isFinite(minX)) return null;\n return { minX, minY, maxX, maxY };\n}\n\nexport function Whiteboard({\n data,\n className,\n initialZoom,\n initialCenter,\n fitOnLoad,\n onValidationError,\n \"aria-label\": ariaLabel,\n}: WhiteboardProps) {\n const validation = useMemo(() => validateScene(data), [data]);\n const scene = validation.ok ? validation.scene : null;\n\n // EC-6: side effects only inside useEffect — never call user callbacks in render.\n useEffect(() => {\n if (!validation.ok && onValidationError) {\n onValidationError(validation.errors);\n }\n }, [validation, onValidationError]);\n\n // Stable rough.js generator across renders.\n const generator: RoughGenerator | null = useMemo(() => {\n if (typeof globalThis === \"undefined\") return null;\n try {\n return rough.generator();\n } catch {\n return null;\n }\n }, []);\n\n // Fallback dimensions for invalid scenes (still render a valid svg).\n const sceneWidth = scene?.width ?? 400;\n const sceneHeight = scene?.height ?? 300;\n const sceneBackground = scene?.background;\n\n const viewport = useViewport({\n width: sceneWidth,\n height: sceneHeight,\n initialZoom,\n initialCenter,\n });\n\n const svgRef = useRef<SVGSVGElement | null>(null);\n\n const fitTo = viewport.fitTo;\n // EC-14: fitOnLoad must run in useEffect (after mount), not during render.\n useEffect(() => {\n if (!fitOnLoad || !scene) return;\n const bounds = computeBounds(scene);\n if (!bounds) return;\n fitTo(bounds, { width: sceneWidth, height: sceneHeight });\n }, [fitOnLoad, scene, sceneWidth, sceneHeight, fitTo]);\n\n const handlers = usePointerPan(svgRef, viewport, {\n width: sceneWidth,\n height: sceneHeight,\n });\n\n const label = ariaLabel ?? \"Whiteboard diagram\";\n\n return (\n <svg\n ref={svgRef}\n viewBox={viewport.viewBox({ width: sceneWidth, height: sceneHeight })}\n width={sceneWidth}\n height={sceneHeight}\n className={className}\n role=\"img\"\n aria-label={label}\n xmlns=\"http://www.w3.org/2000/svg\"\n data-whiteboard-state={scene ? \"ok\" : \"invalid\"}\n style={{ touchAction: \"none\", userSelect: \"none\" }}\n {...handlers}\n >\n <title>{label}</title>\n {sceneBackground ? (\n <rect\n x={0}\n y={0}\n width={sceneWidth}\n height={sceneHeight}\n fill={sceneBackground}\n data-layer=\"background\"\n />\n ) : null}\n {scene && generator ? renderScene(scene, generator) : null}\n </svg>\n );\n}\n"]}
|
package/llms.txt
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# @theokit/ui — Theo UI (Violet Forge)
|
|
2
|
+
|
|
3
|
+
> React component library for AI-agent surfaces and cloud (PaaS) dashboards. 121 components (92 primitives + 29 composites), framework-agnostic (React peer-dep only), ESM-only, Apache-2.0. Built on Radix UI + CVA + lucide-react + Tailwind v4. Same Radix foundation as shadcn — the wedge is the agent/PaaS-specific components built on top.
|
|
4
|
+
|
|
5
|
+
This file follows the [llms.txt convention](https://llmstxt.org/) and gives an LLM the **factual ground truth** of the project: package name, import paths, component inventory, locked conventions, anti-patterns, and links to the canonical documentation. Treat the bullets below as non-negotiable contracts unless the source files contradict them — in which case the source files win and this file is stale.
|
|
6
|
+
|
|
7
|
+
## Project metadata
|
|
8
|
+
|
|
9
|
+
- **npm package:** `@theokit/ui`
|
|
10
|
+
- **Current version:** `0.12.0-next.0` (npm dist-tag `next`; latest release line)
|
|
11
|
+
- **License:** Apache-2.0
|
|
12
|
+
- **Repository:** `https://github.com/usetheodev/theo-ui`
|
|
13
|
+
- **Docs site:** `https://docs.usetheo.dev/theoui`
|
|
14
|
+
- **Registry (shadcn CLI):** `https://usetheodev.github.io/theo-ui/r/{slug}.json`
|
|
15
|
+
- **Design-system codename:** Violet Forge
|
|
16
|
+
- **Module format:** ESM only (no CJS). `"type": "module"`. Side-effects on `**/*.css`.
|
|
17
|
+
- **React peer range:** `>=18.2.0 <20` (works with 18.x and 19.x)
|
|
18
|
+
- **Distribution:** npm package install OR copy-paste source via shadcn CLI (registry). Both paths are first-class.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Full package (recommended for new projects)
|
|
24
|
+
pnpm add @theokit/ui@next
|
|
25
|
+
|
|
26
|
+
# Per-component copy (shadcn-style)
|
|
27
|
+
npx shadcn@latest add https://usetheodev.github.io/theo-ui/r/copy-button.json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Import path canonical form
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
// All components ship via the single barrel.
|
|
34
|
+
import { Button, Table, ConfirmDialog, CopyButton } from "@theokit/ui";
|
|
35
|
+
|
|
36
|
+
// Themes + provider:
|
|
37
|
+
import { ThemeProvider, violetForge, classicPaper, auroraTerminal } from "@theokit/ui";
|
|
38
|
+
|
|
39
|
+
// Pure utility (no React):
|
|
40
|
+
import { cn } from "@theokit/ui";
|
|
41
|
+
|
|
42
|
+
// Engines ship under subpaths (separate bundles, opt-in peer-deps):
|
|
43
|
+
import { Whiteboard } from "@theokit/ui/whiteboard";
|
|
44
|
+
import { Slide } from "@theokit/ui/slide";
|
|
45
|
+
import { SlideDeck } from "@theokit/ui/slide-deck";
|
|
46
|
+
import { Mermaid } from "@theokit/ui/slide/plugins/mermaid";
|
|
47
|
+
import { Math } from "@theokit/ui/slide/plugins/math";
|
|
48
|
+
import { Shiki } from "@theokit/ui/slide/plugins/shiki";
|
|
49
|
+
import { Emoji } from "@theokit/ui/slide/plugins/emoji";
|
|
50
|
+
import { theoUIVitePlugin } from "@theokit/ui/vite-plugin";
|
|
51
|
+
import "@theokit/ui/preset"; // Tailwind v4 preset (zero-config)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
There are **134 subpath exports** in `package.json#exports` — one per component plus engine entry points. **As of 0.10.0-next.0** (Brief #4), per-component subpath imports (`@theokit/ui/button`) point at real per-component dist files (`dist/primitives/button/index.js`) instead of the barrel — switching to subpath form measurably shrinks the consumer's `@theokit/ui` chunk by dropping unused components. Before 0.10, subpath imports were cosmetic (all aliased the barrel). The barrel form keeps working, additive migration shape (same as `@mui/material`).
|
|
55
|
+
|
|
56
|
+
## Peer dependencies (required vs optional)
|
|
57
|
+
|
|
58
|
+
**Required for the main barrel:**
|
|
59
|
+
- `react >=18.2.0 <20`
|
|
60
|
+
- `react-dom >=18.2.0 <20`
|
|
61
|
+
- `tailwindcss ^4.0.0`
|
|
62
|
+
|
|
63
|
+
**Optional (only required if you use the matching engine subpath):**
|
|
64
|
+
- `@tailwindcss/vite ^4.0.0`, `vite ^6 || ^7` — for `@theokit/ui/vite-plugin`
|
|
65
|
+
- `roughjs ^4.6`, `perfect-freehand ^1.2` — for `@theokit/ui/whiteboard`
|
|
66
|
+
- `mdast-util-from-markdown`, `mdast-util-gfm`, `mdast-util-to-hast`, `hast-util-sanitize`, `hast-util-to-jsx-runtime`, `micromark-extension-gfm`, `unist-util-visit`, `unist-util-visit-parents`, `yaml` — for `@theokit/ui/slide`
|
|
67
|
+
- `shiki ^1.0` — for `@theokit/ui/slide/plugins/shiki`
|
|
68
|
+
- `katex ^0.16`, `mdast-util-math`, `micromark-extension-math` — for `@theokit/ui/slide/plugins/math`
|
|
69
|
+
- `mermaid ^11.0` — for `@theokit/ui/slide/plugins/mermaid`
|
|
70
|
+
- `hast-util-from-html` — for `@theokit/ui/slide/plugins/emoji`
|
|
71
|
+
|
|
72
|
+
**Already bundled (do NOT install separately):** `@radix-ui/*`, `class-variance-authority`, `clsx`, `cmdk`, `lucide-react`, `tailwind-merge`. These are `dependencies`, not peer.
|
|
73
|
+
|
|
74
|
+
## Taxonomy (mechanical rule, gate-enforced)
|
|
75
|
+
|
|
76
|
+
- **Primitive** = a component that imports **zero** other `@theokit/ui` components. Lives in `src/components/primitives/`.
|
|
77
|
+
- **Composite** = a component that imports **one or more** primitives via their barrel `index.js`. Lives in `src/components/composites/`.
|
|
78
|
+
- The gate `scripts/validate-quality-gates.ts` is **hard-fail** if either rule is violated. A primitive that grows to need a sibling primitive must be **promoted to composite** by moving the folder + renaming via PR with rationale.
|
|
79
|
+
- Composites import siblings via barrel: `import { Button } from "../../primitives/button/index.js"` — NOT via the raw `.tsx` file (also gate-enforced).
|
|
80
|
+
- Sub-component pattern (e.g., `Table.Header`, `Sidebar.Item`, `DangerZone.Action`) is implemented via `Object.assign(Root, { SubA, SubB })` — Sidebar-style. Single import surface, attached as static properties on the root.
|
|
81
|
+
|
|
82
|
+
## Theme system
|
|
83
|
+
|
|
84
|
+
- **Provider:** `<ThemeProvider initial="violet-forge">{...}</ThemeProvider>`. Wrap once at the app root.
|
|
85
|
+
- **Built-in themes (10):** `violetForge` (default), `classicPaper`, `auroraTerminal`, `vercelMono`, `githubDark`, `dracula`, `oneDark`, `anthropicStyle`, `openaiStyle`, `linearGlass`.
|
|
86
|
+
- **Custom themes:** `defineTheme({ name, mode, fonts, palette })` — returns a `Theme` object you pass into `<ThemeProvider extra={[myTheme]} />`.
|
|
87
|
+
- **Color helpers:** `hex("#7c5cff")`, `rgb(124, 92, 255)` — both return CSS-ready strings.
|
|
88
|
+
- **Density:** `useDensity()` hook returns `"compact" | "comfortable" | "cozy"`. Cascading via `<DensityProvider>`.
|
|
89
|
+
- **Fonts (locked):** Geist Sans (display + body) + Geist Mono (mono). Loaded via CDN by default (`dist/fonts-cdn.css`) or locally (`dist/fonts.css`).
|
|
90
|
+
- **Tailwind v4:** CSS-first config via `@theokit/ui/preset` (zero JS config). v3 legacy preset available at `@theokit/ui/preset-v3-legacy`.
|
|
91
|
+
|
|
92
|
+
## Component catalog — primitives (89)
|
|
93
|
+
|
|
94
|
+
Located in `src/components/primitives/{slug}/`. Each ships `.tsx` + `.test.tsx` + `.stories.tsx` + `index.ts` + a `registry/{slug}.json` descriptor.
|
|
95
|
+
|
|
96
|
+
`agent-error-card`, `agent-event`, `agent-handoff`, `agent-profile`, `agent-starting-state`, `agent-streaming`, **`alert`** (NEW 0.9), `artifact-preview`, `attachment-chip`, `audit-log-entry`, `auto-compact-notice`, `avatar`, `badge`, `browser-controls`, `build-log-stream`, `button`, `capability-indicator`, `card`, `chat-thread`, `checkbox`, `context-card`, `context-window-bar`, **`copy-button`** (0.8), `cost-meter`, `created-files-card`, `cron-job-card`, **`danger-zone`** (0.8), `dialog`, `diff-viewer`, `empty-state`, `folder-context-card`, `folder-selector`, `form-field`, `hook-config`, `hook-event-log`, `input`, `intent-selector`, `label`, `lane-board`, `login-split`, `mcp-server-card`, `memory-editor`, `mention-menu`, `metrics-panel`, `model-card`, `model-selector`, **`pagination`** (NEW 0.9), `permission-matrix`, **`plan-badge`** (0.7), **`progress`** (0.7), `progress-checklist`, `project-switcher`, `quick-action-chips`, `radio-group`, `recent-folders-list`, `rule-card`, `running-tasks-panel`, `run-stats`, `scroll-area`, `select`, `session-list-item`, `session-timeline`, `sheet`, `sidebar`, `skeleton`, `skill-card`, `slide`, `social-auth-row`, **`stat-tile`** (0.8), **`status-dot`** (0.8), `steps-rail`, `sub-agent-dispatch`, `switch`, `system-prompt-editor`, **`table`** (0.8), `tabs`, `task-plan`, `terminal-panel`, `textarea`, **`timestamp`** (0.8), `toast`, `token-usage-chart`, `tool-call`, `tool-call-card`, `tool-result`, `tools-list`, `tooltip`, `topnav`, `whiteboard`.
|
|
97
|
+
|
|
98
|
+
## Component catalog — composites (27)
|
|
99
|
+
|
|
100
|
+
Located in `src/components/composites/{slug}/`.
|
|
101
|
+
|
|
102
|
+
**`account-menu`** (0.7), `agent-composer`, `agent-editor`, `agent-stream`, `agent-timeline`, `approval-card`, `chat-composer`, `chat-message`, **`code-block`** (NEW 0.8), `command-palette`, **`confirm-dialog`** (NEW 0.8), `cron-jobs-list`, `deployment-row`, `domain-config`, `env-var-editor`, `mcp-server-list`, `permission-modal`, `preview-env-card`, `preview-panel`, `project-card`, `rollback-ui`, `rule-editor`, `skill-editor`, `skills-list`, `slide-deck`, `task-header`, **`usage-meter`** (0.7).
|
|
103
|
+
|
|
104
|
+
## Recent deliveries (PaaS shape)
|
|
105
|
+
|
|
106
|
+
- **0.12.0-next.0 (DESIGN.md + companion agent skill, 2026-05-25):** Two LLM-facing artifacts that complement `llms.txt`. **`DESIGN.md`** at repo root — 9-section visual spec following the awesome-design-md canonical structure (Visual Theme · Color Palette · Typography · Layout · Depth & Elevation · Components · Responsive · Do's and Don'ts · Agent Prompt Guide). Tokens mirror `src/styles/tokens.css` + `src/themes/violet-forge.ts`. Shipped via `package.json > files`. **`skills/theo-ui/`** companion skill installable via `npx skills add usetheodev/theo-ui` (vercel-labs/skills CLI): 4 verbs (default build / `audit` / `migrate` / `catalog`), 32 universal slop-test gates + surface-specific extensions, pre-emit critique on 6 axes (Library-fit · Token-fidelity · Composition · A11y · Restraint · Voice), 12 page archetypes, 5 surfaces (agent-chat · cloud-dashboard · settings-form · marketing · auth). Distributed via GitHub (not npm). Zero new peer-deps; zero source-code changes; pure docs/skill addition.
|
|
107
|
+
- **0.11.0-next.0 (Brief #5 — 3 dashboard primitives + 2 pre-reqs, 2026-05-25):** Closes 3 measured TheoCloud Deep Review findings. `PinInput` (6-box OTP input with auto-advance, paste handling, mask, error — closes § 2.12 P2). `DataTable` composite (sortable + sticky + expandable rows with `expandMode="single"|"multiple"` + row actions via DropdownMenu + client-side pagination + loading skeleton + empty state — closes Top-5 #2 / § 2.2 + § 2.4 P1). `PageShell` composite (page-level scaffold with state precedence loading > error > empty > children; does NOT manage document.title — exposes `onTitleChange` callback for consumer-scope hook — closes CC-3 indirect; D3 scope decision). Plus 2 explicit pre-requisites the brief assumed existed: `DropdownMenu` primitive (Radix wrapper consolidating 5 prior direct usages) and `ActionBar` primitive (search + filter + primary action; composed by PageShell). Zero new peer-deps. ADR `page-shell-composite-pattern.md` documents the scope-narrowing decision.
|
|
108
|
+
- **0.10.0-next.0 (Brief #4 — subpath tree-shaking, build pipeline fix):** ~100 cosmetic subpath exports (every entry pointed at the same 417 KB barrel) replaced with real per-component dist files via tsup auto-glob + `splitting: true`. `dist/index.js` shrank from 417 KB → 49 KB (−88%) because all component code now lives in 119 shared chunks. Per-component dist files (~150-200 bytes each) are tiny re-export wrappers. Per-component `.d.ts` not emitted (would OOM tsup worker pool) — types resolve via barrel `dist/index.d.ts`. `scripts/regen-subpath-exports.ts` runs after every build to keep `package.json#exports` honest (refuses to write if any straggler points at the barrel). Zero breaking change; consumer migration is opt-in file-by-file. ADR at `.claude/knowledge-base/decisions/subpath-exports-per-component.md`.
|
|
109
|
+
- **0.9.0-next.0 (Brief #3 — deferred follow-ups, 2 components):** `Alert` (persistent inline notice; 4 intents — info/success/warning/destructive — with mapped lucide icons and role=alert for destructive vs role=status for others; optional title/description/action/onDismiss), `Pagination` (accessible nav landmark with first/prev/numbers/next/last + visual ellipses + aria-current=page; keyboard nav ArrowLeft/Right/Home/End; configurable siblingCount + jump buttons + size; returns null when totalPages <= 1; exports a pure `computePageRange` helper for unit-testing the range logic in isolation). Zero new peer-deps. Brief #3 consumer: TheoCloud `<VerificationBanner>` → 3-line `<Alert>`.
|
|
110
|
+
- **0.8.0-next.0 (Brief #2 — cross-cutting, 8 components):** `Table` (sub-components + sortable headers), `StatusDot` (5 kinds + auto-pulse), `CopyButton` (clipboard + `aria-live` + SSR-safe), `Timestamp` (`Intl.RelativeTimeFormat`, native `title` tooltip, Unix ms only), `StatTile` (dual button/div mode), `DangerZone` (`.Action` sub-component), `ConfirmDialog` (typed-phrase guard + async loading + Enter-to-confirm), `CodeBlock` (terminal prefix + caption + raw-code copy). Consumer: TheoCloud dashboard. Zero new peer-deps; bundle +5.4% (rebaselined).
|
|
111
|
+
- **0.7.0-next.0 (Brief #1 — PaaS-shape, 4 components):** `UsageMeter` (multi-metric, over-quota warning + clamping), `Progress` (4 intents + indeterminate + motion-reduce aware), `PlanBadge` (5 canonical tiers), `AccountMenu` (avatar + name + plan + secondary, dual button/div).
|
|
112
|
+
|
|
113
|
+
## Component conventions (do this)
|
|
114
|
+
|
|
115
|
+
Every component file MUST:
|
|
116
|
+
|
|
117
|
+
1. Use `forwardRef<HTMLElementType, Props>` and set `displayName`. Example: `MyComponent.displayName = "MyComponent";`.
|
|
118
|
+
2. Compose classes via `cn(...)` from `lib/cn.js` (`tailwind-merge` + `clsx` underneath).
|
|
119
|
+
3. Use **design tokens** only — never raw hex/rgb. Approved tokens: `bg-card`, `bg-muted`, `bg-muted/40`, `bg-primary`, `bg-primary/10`, `bg-success`, `bg-warning`, `bg-destructive`, `bg-destructive/[0.02]`, `text-foreground`, `text-muted-foreground`, `text-success`, `text-warning`, `text-destructive`, `border-border/40`, `border-border/60`, `border-destructive/30`, `text-card-foreground`, `text-primary-foreground`, `ring-ring`, etc.
|
|
120
|
+
4. Use **typography scale**: `text-display-md`, `text-title-sm`, `text-body-sm`, `text-label`, `text-label-caps`, `font-display`, `font-sans`, `font-mono` — never raw `text-xl`/`text-base`/`text-sm`.
|
|
121
|
+
5. Use `lucide-react` for icons. Never inline SVG. Icons rendered as components (`<Copy aria-hidden="true" className="size-3.5" />`).
|
|
122
|
+
6. Use CVA (`class-variance-authority`) for variant APIs that have ≥3 options (Button, Badge, Progress intent, etc.).
|
|
123
|
+
7. Pass `aria-label` for icon-only triggers. Use `<span className="sr-only" aria-live="polite">` for state announcements (CopyButton pattern).
|
|
124
|
+
8. Tests use `vitest` + `@testing-library/react` + `vitest-axe`. Every interactive primitive ships `expect(await axe(container)).toHaveNoViolations()`. Async assertions use `findBy*` with `{ timeout: 5000 }` headroom for parallel vitest pool.
|
|
125
|
+
9. Stories ship in Ladle (`.stories.tsx`). Title pattern: `"Primitives / {Category} / {Name}"` or `"Composites / {Category} / {Name}"`.
|
|
126
|
+
10. Registry descriptor in `registry/{slug}.json` with shadcn schema. Each entry declares `dependencies` (npm) + `registryDependencies` (other registry items in this project).
|
|
127
|
+
|
|
128
|
+
## Anti-patterns (do NOT)
|
|
129
|
+
|
|
130
|
+
- **Do NOT** add raw hex/rgb. Always use tokens. The design-audit gate fails the build if it finds them.
|
|
131
|
+
- **Do NOT** install Radix / CVA / lucide-react separately — they're bundled `dependencies`.
|
|
132
|
+
- **Do NOT** import a sibling primitive into another primitive (taxonomy gate hard-fails). Either inline the dep or promote to composite.
|
|
133
|
+
- **Do NOT** import via `../../primitives/foo/foo.js` from a composite — use `../../primitives/foo/index.js` (gate hard-fails).
|
|
134
|
+
- **Do NOT** wrap dropdown/dialog/select in your own Portal. Radix manages portals correctly.
|
|
135
|
+
- **Do NOT** disable a quality gate or add `eslint-disable`/`biome-ignore` to silence one — fix the root cause. Acceptable biome-ignore comments must include a `WAI-ARIA …` or equivalent justification.
|
|
136
|
+
- **Do NOT** roll your own clipboard, focus-trap, accessible dialog, color parser, markdown renderer, syntax highlighter, or relative-time formatter — use `<CopyButton>`, Radix Dialog, `Intl.RelativeTimeFormat`, etc.
|
|
137
|
+
- **Do NOT** ship CJS (`require()`). ESM only. The TypeScript output is `.js` with `.d.ts` siblings.
|
|
138
|
+
- **Do NOT** rename the locked names (see below) without a strategic review.
|
|
139
|
+
- **Do NOT** use emojis in code, README, JSDoc, or CHANGELOG. (User-facing copy in docs is OK if explicitly requested.)
|
|
140
|
+
- **Do NOT** invent integration that doesn't exist. As of 2026-05-23, `@theokit/ui` has **no** import from `@theokit/sdk`, `theokit`, or `theo-code`. Verify with `grep` before claiming wiring.
|
|
141
|
+
|
|
142
|
+
## Locked names (immutable without strategic review)
|
|
143
|
+
|
|
144
|
+
| Item | Value |
|
|
145
|
+
|---|---|
|
|
146
|
+
| npm package | `@theokit/ui` |
|
|
147
|
+
| Codename | Violet Forge |
|
|
148
|
+
| Default theme | `violet-forge` |
|
|
149
|
+
| Built-in themes (3 originals) | `violet-forge`, `classic-paper`, `aurora-terminal` |
|
|
150
|
+
| ThemeProvider component | `<ThemeProvider />` |
|
|
151
|
+
| Registry endpoint (planned canonical) | `ui.usetheo.dev/r/*.json` |
|
|
152
|
+
| Module format | ESM only |
|
|
153
|
+
| Quality-gate command | `pnpm quality:gates` |
|
|
154
|
+
| Test framework | Vitest |
|
|
155
|
+
| Stories framework | Ladle |
|
|
156
|
+
| Linter / formatter | Biome (`biome check`, `biome format`) |
|
|
157
|
+
| Component taxonomy | `primitive` (no internal deps) vs `composite` (≥1 internal dep) |
|
|
158
|
+
| Fonts | Geist Sans + Geist Mono (CDN by default) |
|
|
159
|
+
|
|
160
|
+
## Engines (subpath-isolated, opt-in)
|
|
161
|
+
|
|
162
|
+
These ship under their own subpath because they require heavy peer-deps. **Do NOT** include in the main barrel.
|
|
163
|
+
|
|
164
|
+
| Engine | Subpath | Required peer-deps |
|
|
165
|
+
|---|---|---|
|
|
166
|
+
| Whiteboard (Excalidraw-style view) | `@theokit/ui/whiteboard` | `roughjs`, `perfect-freehand` |
|
|
167
|
+
| Slide (Marp-style view) | `@theokit/ui/slide` | `mdast-util-*`, `hast-util-*`, `micromark-extension-gfm`, `unist-util-visit*`, `yaml` |
|
|
168
|
+
| SlideDeck | `@theokit/ui/slide-deck` | inherits from Slide |
|
|
169
|
+
| Slide plugin — Shiki | `@theokit/ui/slide/plugins/shiki` | `shiki` |
|
|
170
|
+
| Slide plugin — Math (KaTeX) | `@theokit/ui/slide/plugins/math` | `katex`, `mdast-util-math`, `micromark-extension-math` |
|
|
171
|
+
| Slide plugin — Mermaid | `@theokit/ui/slide/plugins/mermaid` | `mermaid` |
|
|
172
|
+
| Slide plugin — Emoji | `@theokit/ui/slide/plugins/emoji` | `hast-util-from-html` |
|
|
173
|
+
| Vite plugin | `@theokit/ui/vite-plugin` | `vite ^6 || ^7`, `@tailwindcss/vite` |
|
|
174
|
+
|
|
175
|
+
All engines documented under RFC 0001 / 0002 / 0003 / 0004 in `docs/rfcs/`. View-only (no editing) by design.
|
|
176
|
+
|
|
177
|
+
## Quality gates (run via `pnpm quality:gates`)
|
|
178
|
+
|
|
179
|
+
The full chain runs in CI and must be 100% green for any PR to merge:
|
|
180
|
+
|
|
181
|
+
1. `format:check` — Biome formatter
|
|
182
|
+
2. `lint:ci` — Biome linter (strict)
|
|
183
|
+
3. `typecheck` — `tsc --noEmit` (strict TS)
|
|
184
|
+
4. `test` — Vitest run (1532+ tests including `vitest-axe` a11y)
|
|
185
|
+
5. `build` — tsup (ESM + d.ts + CSS)
|
|
186
|
+
6. `registry:build` + `registry:validate` — shadcn descriptors
|
|
187
|
+
7. `quality:structure` — taxonomy + readme drift + design-audit + test/story coverage
|
|
188
|
+
8. `quality:bundle` — `dist/index.js` size delta within ±5% baseline (rebaseline explicit via `--update`)
|
|
189
|
+
9. `quality:a11y` — every interactive Ladle story axe-validated (~226 tests)
|
|
190
|
+
10. `ladle:build` — verify Ladle compiles
|
|
191
|
+
11. `dogfood:*` — end-to-end smoke against each engine
|
|
192
|
+
|
|
193
|
+
## Test conventions
|
|
194
|
+
|
|
195
|
+
- Framework: **Vitest** (NOT Jest). Use `vi.fn()`, `vi.spyOn()`, `vi.useFakeTimers()`.
|
|
196
|
+
- Renderer: `@testing-library/react`. Always `render(<C ... />)`, never manual `ReactDOM.render`.
|
|
197
|
+
- A11y: `import { axe } from "vitest-axe"; expect(await axe(container)).toHaveNoViolations();`
|
|
198
|
+
- Async assertions: `await screen.findByText(...)` (not `getByText` then `waitFor`). For tests under parallel vitest pool stress, add `{ timeout: 5000 }`.
|
|
199
|
+
- Radix dialog tests: use `baseElement` (not `container`) for portal-rendered content. Disable `aria-hidden-focus` rule on axe runs over Dialog content — it's a false positive on Radix's focus-guard spans.
|
|
200
|
+
- Clipboard tests: `vi.stubGlobal("navigator", { clipboard: { writeText: vi.fn() } });`.
|
|
201
|
+
- Time/Date tests: `vi.useFakeTimers(); vi.setSystemTime(new Date("2026-05-23T12:00:00Z"));`.
|
|
202
|
+
|
|
203
|
+
## Stories convention (Ladle)
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
import type { Story } from "@ladle/react";
|
|
207
|
+
import { MyComponent } from "./my-component.js";
|
|
208
|
+
|
|
209
|
+
export default { title: "Primitives / Category / MyComponent" };
|
|
210
|
+
|
|
211
|
+
export const Default: Story = () => <MyComponent prop="value" />;
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Run dev server: `pnpm dev` (Ladle on `http://localhost:61000`). Build static: `pnpm ladle:build`. Title pattern is enforced for sidebar grouping.
|
|
215
|
+
|
|
216
|
+
## Documentation URLs (canonical)
|
|
217
|
+
|
|
218
|
+
- **Site:** `https://docs.usetheo.dev/theoui`
|
|
219
|
+
- **Per-component MDX pages (curated, not auto-gen):**
|
|
220
|
+
- Primitives: `https://docs.usetheo.dev/theoui/primitives/{slug}`
|
|
221
|
+
- Composites: most live under their domain dir — `infra/`, `code/`, `agent/`, `auth/`, `tools/`, `models/`, `tasks/`. Examples:
|
|
222
|
+
- `https://docs.usetheo.dev/theoui/infra/account-menu` (PaaS surface)
|
|
223
|
+
- `https://docs.usetheo.dev/theoui/infra/usage-meter`
|
|
224
|
+
- `https://docs.usetheo.dev/theoui/code/code-block`
|
|
225
|
+
- `https://docs.usetheo.dev/theoui/primitives/table`
|
|
226
|
+
- `https://docs.usetheo.dev/theoui/primitives/confirm-dialog`
|
|
227
|
+
- **Theming guide:** `https://docs.usetheo.dev/theoui/theming`
|
|
228
|
+
- **Engines:** `https://docs.usetheo.dev/theoui/engines/{whiteboard,slide,slide-deck}`
|
|
229
|
+
- **CHANGELOG:** `https://github.com/usetheodev/theo-ui/blob/main/CHANGELOG.md`
|
|
230
|
+
|
|
231
|
+
## Source-of-truth files (read these before claiming anything)
|
|
232
|
+
|
|
233
|
+
1. `/CLAUDE.md` — project contract (locked names, taxonomy gate, voice/tone scope, inviolable rules)
|
|
234
|
+
2. `/README.md` — public catalog + quality gates + dev scripts (auto-synced from filesystem by `pnpm sync:readme`)
|
|
235
|
+
3. `/CHANGELOG.md` — every release entry, including [Unreleased] section
|
|
236
|
+
4. `/package.json#exports` — the authoritative list of subpath imports (auto-synced by `pnpm sync:exports`)
|
|
237
|
+
5. `/src/index.ts` — the barrel; every public component appears here
|
|
238
|
+
6. `/docs/architecture.md` — folder layout + module boundaries
|
|
239
|
+
7. `/docs/design-system.md` — tokens, fonts, type scale (Geist + Vercel scale, locked)
|
|
240
|
+
8. `/docs/rfcs/*.md` — engine RFCs (whiteboard 0001, slide 0002, slide-deck 0003, slide-rich-content 0004, themes 0007, integration 0008, chat-message 0009)
|
|
241
|
+
9. `/scripts/validate-quality-gates.ts` — the taxonomy + structure gate
|
|
242
|
+
10. `/.claude/knowledge-base/plans/*.md` — every change of ≥3 phases has a written plan; the most recent is `dashboard-paas-primitives-2-plan.md` (Brief #2)
|
|
243
|
+
|
|
244
|
+
## How to add a new component (the rote checklist)
|
|
245
|
+
|
|
246
|
+
1. Decide taxonomy: does it import another `@theokit/ui` component? If yes → composite. If no → primitive.
|
|
247
|
+
2. Create folder: `src/components/{primitives,composites}/{kebab-name}/`
|
|
248
|
+
3. Create 4 files: `{slug}.tsx`, `{slug}.test.tsx`, `{slug}.stories.tsx`, `index.ts`
|
|
249
|
+
4. Implement with `forwardRef` + `displayName` + `cn()` + lucide icons + design tokens + typography scale
|
|
250
|
+
5. Tests: ≥6 unit tests including 1 `vitest-axe` assertion
|
|
251
|
+
6. Stories: ≥3 Ladle stories (variants/sizes/states)
|
|
252
|
+
7. Add registry descriptor: `registry/{slug}.json` with `$schema`, `name`, `type: "registry:ui"`, `title`, `description`, `dependencies`, `registryDependencies`, `files`
|
|
253
|
+
8. Add export to `src/index.ts` (the barrel)
|
|
254
|
+
9. Run `pnpm sync:exports && pnpm sync:readme` to regenerate `package.json#exports` + README + architecture catalog + Ladle stats
|
|
255
|
+
10. Add CHANGELOG entry under `## [Unreleased]` → `### Added` with one bullet per component
|
|
256
|
+
11. Run `pnpm quality:gates` — must be 100% green
|
|
257
|
+
12. If shipping to consumers, also write a curated MDX page in `theo-opendocs` (NEVER use auto-gen `/components/` dir — that's broken legacy)
|
|
258
|
+
|
|
259
|
+
## Cross-project positioning
|
|
260
|
+
|
|
261
|
+
`@theokit/ui` is the **UI pillar** of the `usetheo` ecosystem. Other pillars:
|
|
262
|
+
|
|
263
|
+
- **Harness** — `@theokit/sdk` (Claude Agent SDK consumer). No current import from `@theokit/ui`.
|
|
264
|
+
- **Skills** — `theokit` (agent framework). No current import.
|
|
265
|
+
- **Runtime** — Theo PaaS (cloud platform, pre-release). No current import; `<DeploymentRow>`, `<BuildLogStream>`, `<RollbackUI>`, `<EnvVarEditor>`, `<DomainConfig>`, `<PreviewEnvCard>`, `<ProjectCard>`, `<MetricsPanel>`, and the new Brief #1 + #2 components are designed for it but currently unused.
|
|
266
|
+
|
|
267
|
+
`@theokit/ui` is **community auxiliary**: Apache-2.0, usable standalone, no commitment to the rest of the stack. The integration story above is aspirational; verify with `grep` before claiming wiring exists in any consumer.
|
|
268
|
+
|
|
269
|
+
## When this file is stale
|
|
270
|
+
|
|
271
|
+
The code, the README, and the `package.json#exports` map are **authoritative**. If `llms.txt` disagrees with them, the code wins — update this file via PR with a one-line rationale. Locked names (Section "Locked names") and voice/narrative rules require a strategic review at the monorepo level before being weakened or repealed.
|
|
272
|
+
|
|
273
|
+
— Generated 2026-05-23 (last updated 2026-05-25 for 0.12.0-next.0 / DESIGN.md + companion agent skill) from filesystem inventory + `CLAUDE.md` + `README.md`. Regenerate by inspecting `src/components/{primitives,composites}/*/` directories and updating the catalog sections above.
|