@cryptiklemur/lattice 1.46.7 → 2.0.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.
Files changed (599) hide show
  1. package/README.md +14 -36
  2. package/bin/lattice +5 -21
  3. package/dist/client/assets/abap-DOv5zRgd.js +1 -0
  4. package/dist/client/assets/actionscript-3-D_b0n2Ff.js +1 -0
  5. package/dist/client/assets/ada-C6m8O36S.js +1 -0
  6. package/dist/client/assets/andromeeda-LdzAHaKR.js +1 -0
  7. package/dist/client/assets/angular-html-BBi1Szz5.js +1 -0
  8. package/dist/client/assets/angular-ts-2PMpSPqc.js +1 -0
  9. package/dist/client/assets/apache-CE7PmWoU.js +1 -0
  10. package/dist/client/assets/apex-DOfNfL0V.js +1 -0
  11. package/dist/client/assets/apl-B-NEtBvQ.js +1 -0
  12. package/dist/client/assets/applescript-D4zGaScB.js +1 -0
  13. package/dist/client/assets/ara-DMoCP0pJ.js +1 -0
  14. package/dist/client/assets/asciidoc-BkmPq932.js +1 -0
  15. package/dist/client/assets/asm-ClIKbvsu.js +1 -0
  16. package/dist/client/assets/astro-mxH1DA5Z.js +1 -0
  17. package/dist/client/assets/aurora-x-DTcNXZIS.js +1 -0
  18. package/dist/client/assets/awk-D1ZOsISX.js +1 -0
  19. package/dist/client/assets/ayu-dark-DpNcORnA.js +1 -0
  20. package/dist/client/assets/ayu-light-lHqf0ddo.js +1 -0
  21. package/dist/client/assets/ayu-mirage-Dji5RWiH.js +1 -0
  22. package/dist/client/assets/ballerina-H14_EqPr.js +1 -0
  23. package/dist/client/assets/bat-cyb3gF8B.js +1 -0
  24. package/dist/client/assets/beancount-D84pBacF.js +1 -0
  25. package/dist/client/assets/berry-B29XeKK4.js +1 -0
  26. package/dist/client/assets/bibtex-Hs7VvQaV.js +1 -0
  27. package/dist/client/assets/bicep-CugTE5CQ.js +1 -0
  28. package/dist/client/assets/bird2-mieRHotO.js +1 -0
  29. package/dist/client/assets/blade-BUQ9XSm3.js +1 -0
  30. package/dist/client/assets/bsl-BRmzGEWg.js +1 -0
  31. package/dist/client/assets/c-DrQixLw7.js +1 -0
  32. package/dist/client/assets/c3-Dx2gByXW.js +1 -0
  33. package/dist/client/assets/cadence-CCTSwj3w.js +1 -0
  34. package/dist/client/assets/cairo-CaIu88t6.js +1 -0
  35. package/dist/client/assets/catppuccin-frappe-DQrU04q0.js +1 -0
  36. package/dist/client/assets/catppuccin-latte-B_oiWZka.js +1 -0
  37. package/dist/client/assets/catppuccin-macchiato-D8VB2qi4.js +1 -0
  38. package/dist/client/assets/catppuccin-mocha-5vkMJ1Mb.js +1 -0
  39. package/dist/client/assets/clarity-BbUNTPrg.js +1 -0
  40. package/dist/client/assets/clojure-Bcw7lCta.js +1 -0
  41. package/dist/client/assets/cmake-DM0FE-T9.js +1 -0
  42. package/dist/client/assets/cobol-42amjOMh.js +1 -0
  43. package/dist/client/assets/codeowners-CBvEPOlS.js +1 -0
  44. package/dist/client/assets/codeql-CjS8Tp16.js +1 -0
  45. package/dist/client/assets/coffee-CMSEUKyy.js +1 -0
  46. package/dist/client/assets/common-lisp-BCx4dVK8.js +1 -0
  47. package/dist/client/assets/coq-Ddo7YIsR.js +1 -0
  48. package/dist/client/assets/cpp-C4yJBzl2.js +1 -0
  49. package/dist/client/assets/crystal-DZ27EoiA.js +1 -0
  50. package/dist/client/assets/csharp-Kzd7Ey2d.js +1 -0
  51. package/dist/client/assets/css-CdQwkSNm.js +1 -0
  52. package/dist/client/assets/csv-DGwgERVJ.js +1 -0
  53. package/dist/client/assets/cue-CMabdDG0.js +1 -0
  54. package/dist/client/assets/cypher-CJUzJAhQ.js +1 -0
  55. package/dist/client/assets/d-BvLF4qGs.js +1 -0
  56. package/dist/client/assets/dark-plus-BMwvn5lx.js +1 -0
  57. package/dist/client/assets/dart-DxXbDeKR.js +1 -0
  58. package/dist/client/assets/dax-BvrCypuS.js +1 -0
  59. package/dist/client/assets/desktop-BEul_kAS.js +1 -0
  60. package/dist/client/assets/diff-B7rhrwA5.js +1 -0
  61. package/dist/client/assets/dist-CBRIe7YG.js +153 -0
  62. package/dist/client/assets/docker-9Zbx0dQX.js +1 -0
  63. package/dist/client/assets/dotenv-C0epktMv.js +1 -0
  64. package/dist/client/assets/dracula-CBD4ckb0.js +1 -0
  65. package/dist/client/assets/dracula-soft-CuGBZj_h.js +1 -0
  66. package/dist/client/assets/dream-maker-D6UB367x.js +1 -0
  67. package/dist/client/assets/edge-J8VemHZC.js +1 -0
  68. package/dist/client/assets/elixir-DU66qSn_.js +1 -0
  69. package/dist/client/assets/elm-8cz1JjRg.js +1 -0
  70. package/dist/client/assets/emacs-lisp-DFyMFAZA.js +1 -0
  71. package/dist/client/assets/erb-DMl63J6s.js +1 -0
  72. package/dist/client/assets/erlang-LvhGhZI3.js +1 -0
  73. package/dist/client/assets/everforest-dark-BhFNrp2k.js +1 -0
  74. package/dist/client/assets/everforest-light-CpIbZ9aT.js +1 -0
  75. package/dist/client/assets/fennel-CH1ohGYX.js +1 -0
  76. package/dist/client/assets/fish-D2X4h_sR.js +1 -0
  77. package/dist/client/assets/fluent-B_In4uB6.js +1 -0
  78. package/dist/client/assets/fortran-fixed-form-BXvkHMbK.js +1 -0
  79. package/dist/client/assets/fortran-free-form-Bw_JZ1tj.js +1 -0
  80. package/dist/client/assets/fsharp-uxIU8dwY.js +1 -0
  81. package/dist/client/assets/gdresource-DkI-mZL2.js +1 -0
  82. package/dist/client/assets/gdscript-DDro0rs8.js +1 -0
  83. package/dist/client/assets/gdshader-DkUeC1ld.js +1 -0
  84. package/dist/client/assets/genie-khT2hrp-.js +1 -0
  85. package/dist/client/assets/gherkin-CPELKal0.js +1 -0
  86. package/dist/client/assets/git-commit-a3TktZ3A.js +1 -0
  87. package/dist/client/assets/git-rebase-DjlZL8cj.js +1 -0
  88. package/dist/client/assets/github-dark-DQp1Qkx5.js +1 -0
  89. package/dist/client/assets/github-dark-default-BroO-mT3.js +1 -0
  90. package/dist/client/assets/github-dark-dimmed-D8UZ8uTL.js +1 -0
  91. package/dist/client/assets/github-dark-high-contrast-CM0RRMCj.js +1 -0
  92. package/dist/client/assets/github-light-BRTmX4Ht.js +1 -0
  93. package/dist/client/assets/github-light-default-dl7biQ4g.js +1 -0
  94. package/dist/client/assets/github-light-high-contrast-Cvzq8ZXJ.js +1 -0
  95. package/dist/client/assets/gleam-7UVjplRF.js +1 -0
  96. package/dist/client/assets/glimmer-js-Fu7vOQY-.js +1 -0
  97. package/dist/client/assets/glimmer-ts-AJljRs0A.js +1 -0
  98. package/dist/client/assets/glsl-CfodGzSv.js +1 -0
  99. package/dist/client/assets/gn-EcrZPIZo.js +1 -0
  100. package/dist/client/assets/gnuplot-CcsFlqcz.js +1 -0
  101. package/dist/client/assets/go-TqNfhUhh.js +1 -0
  102. package/dist/client/assets/graphql-C8GPKPx1.js +1 -0
  103. package/dist/client/assets/groovy-bfrzFpSZ.js +1 -0
  104. package/dist/client/assets/gruvbox-dark-hard-CBFL_VqK.js +1 -0
  105. package/dist/client/assets/gruvbox-dark-medium-Dn18r-Yz.js +1 -0
  106. package/dist/client/assets/gruvbox-dark-soft-DUyKWd02.js +1 -0
  107. package/dist/client/assets/gruvbox-light-hard-DV9RwKs4.js +1 -0
  108. package/dist/client/assets/gruvbox-light-medium-Ba-VIg48.js +1 -0
  109. package/dist/client/assets/gruvbox-light-soft-CVIZMKFx.js +1 -0
  110. package/dist/client/assets/hack-Gp6OuE21.js +1 -0
  111. package/dist/client/assets/haml-BOyG6GfM.js +1 -0
  112. package/dist/client/assets/handlebars-B9IoVRxd.js +1 -0
  113. package/dist/client/assets/haskell-DzEtL6Zk.js +1 -0
  114. package/dist/client/assets/haxe-wLDEcRoz.js +1 -0
  115. package/dist/client/assets/hcl-C1fs3gTM.js +1 -0
  116. package/dist/client/assets/hjson-B4b85MZo.js +1 -0
  117. package/dist/client/assets/hlsl-JhqkHhML.js +1 -0
  118. package/dist/client/assets/horizon-DMOEeSnA.js +1 -0
  119. package/dist/client/assets/horizon-bright-CPVackS9.js +1 -0
  120. package/dist/client/assets/houston-DSlR9wH9.js +1 -0
  121. package/dist/client/assets/html-CFrSukiU.js +1 -0
  122. package/dist/client/assets/html-derivative-D0_gRK_M.js +1 -0
  123. package/dist/client/assets/http-D4MmFixi.js +1 -0
  124. package/dist/client/assets/hurl-D1xbk-LS.js +1 -0
  125. package/dist/client/assets/hxml-Bdi_kWeE.js +1 -0
  126. package/dist/client/assets/hy-uAHU8420.js +1 -0
  127. package/dist/client/assets/imba-CPCwfD-G.js +1 -0
  128. package/dist/client/assets/index-DrTbNMzI.css +2 -0
  129. package/dist/client/assets/index-ZIuI5BCP.js +284 -0
  130. package/dist/client/assets/ini-2Ew1Qzj6.js +1 -0
  131. package/dist/client/assets/java-CfPMY1Dv.js +1 -0
  132. package/dist/client/assets/javascript-B8vNHeqm.js +1 -0
  133. package/dist/client/assets/jinja-CF0K8bFV.js +1 -0
  134. package/dist/client/assets/jison-BP7my5TL.js +1 -0
  135. package/dist/client/assets/json-TeXNjpMZ.js +1 -0
  136. package/dist/client/assets/json5-Dl8gAgq4.js +1 -0
  137. package/dist/client/assets/jsonc-C9b23pMf.js +1 -0
  138. package/dist/client/assets/jsonl-DkF3QjsY.js +1 -0
  139. package/dist/client/assets/jsonnet-DH4UkOBo.js +1 -0
  140. package/dist/client/assets/jssm-CBV9_O8o.js +1 -0
  141. package/dist/client/assets/jsx-C86NmHc2.js +1 -0
  142. package/dist/client/assets/julia-C58U_aQP.js +1 -0
  143. package/dist/client/assets/just-h6Vco8Qu.js +1 -0
  144. package/dist/client/assets/kanagawa-dragon-DLDXA4f2.js +1 -0
  145. package/dist/client/assets/kanagawa-lotus-qAvw6eOU.js +1 -0
  146. package/dist/client/assets/kanagawa-wave-DFO_g5Mb.js +1 -0
  147. package/dist/client/assets/kdl-BQl-X5Uf.js +1 -0
  148. package/dist/client/assets/kotlin-d6oenWPH.js +1 -0
  149. package/dist/client/assets/kusto-Cpu9Tdho.js +1 -0
  150. package/dist/client/assets/laserwave-Bbquw0Nf.js +1 -0
  151. package/dist/client/assets/latex-DRsNisjT.js +1 -0
  152. package/dist/client/assets/lean-CvyEisyW.js +1 -0
  153. package/dist/client/assets/less-B9RQiV1N.js +1 -0
  154. package/dist/client/assets/light-plus-Ch1Usv7R.js +1 -0
  155. package/dist/client/assets/liquid-C9jXC9M7.js +1 -0
  156. package/dist/client/assets/llvm-DtrwjsAs.js +1 -0
  157. package/dist/client/assets/log-JKbKuM4J.js +1 -0
  158. package/dist/client/assets/logo-BsxZM_eb.js +1 -0
  159. package/dist/client/assets/lua-BUYvdn-F.js +1 -0
  160. package/dist/client/assets/luau-D9oeBRnv.js +1 -0
  161. package/dist/client/assets/make-DLuqI3Sa.js +1 -0
  162. package/dist/client/assets/markdown-hfQzyr6v.js +1 -0
  163. package/dist/client/assets/marko-BqB4tqw-.js +1 -0
  164. package/dist/client/assets/material-theme-darker-yvetTWEr.js +1 -0
  165. package/dist/client/assets/material-theme-kX26WiJU.js +1 -0
  166. package/dist/client/assets/material-theme-lighter-L4j3qddN.js +1 -0
  167. package/dist/client/assets/material-theme-ocean-BnNk1wNQ.js +1 -0
  168. package/dist/client/assets/material-theme-palenight-W0qbGyud.js +1 -0
  169. package/dist/client/assets/matlab-Cz4xBfaA.js +1 -0
  170. package/dist/client/assets/mdc-C8Rs68Nw.js +1 -0
  171. package/dist/client/assets/mdx-Crds6sJw.js +1 -0
  172. package/dist/client/assets/mermaid-Bk1sayFm.js +1 -0
  173. package/dist/client/assets/min-dark-DK6uq44k.js +1 -0
  174. package/dist/client/assets/min-light-lr1QiEOE.js +1 -0
  175. package/dist/client/assets/mipsasm-D3Vr1VJI.js +1 -0
  176. package/dist/client/assets/mojo-D3ai4ATt.js +1 -0
  177. package/dist/client/assets/monokai-DZSWSdmN.js +1 -0
  178. package/dist/client/assets/moonbit-c7XV1V8w.js +1 -0
  179. package/dist/client/assets/move--lg8RSZu.js +1 -0
  180. package/dist/client/assets/narrat-Bn_PlXDl.js +1 -0
  181. package/dist/client/assets/nextflow-DXxhyYjQ.js +1 -0
  182. package/dist/client/assets/nextflow-groovy-CUrXbMOF.js +1 -0
  183. package/dist/client/assets/nginx-Dj6E3HRL.js +1 -0
  184. package/dist/client/assets/night-owl-DnKT96OJ.js +1 -0
  185. package/dist/client/assets/night-owl-light-gVSh6ltn.js +1 -0
  186. package/dist/client/assets/nim-BizJb4iF.js +1 -0
  187. package/dist/client/assets/nix-DE1Q2B1F.js +1 -0
  188. package/dist/client/assets/nord-CbYaE7ZY.js +1 -0
  189. package/dist/client/assets/nushell-BBFYNdNE.js +1 -0
  190. package/dist/client/assets/objective-c-mc6rHp-y.js +1 -0
  191. package/dist/client/assets/objective-cpp-D96wcRis.js +1 -0
  192. package/dist/client/assets/ocaml-Ddt3E4VO.js +1 -0
  193. package/dist/client/assets/odin-BUZTfc03.js +1 -0
  194. package/dist/client/assets/one-dark-pro-CLMO01es.js +1 -0
  195. package/dist/client/assets/one-light-27sfjFDM.js +1 -0
  196. package/dist/client/assets/openscad-C-XxCD_t.js +1 -0
  197. package/dist/client/assets/pascal-BvJwb9Ca.js +1 -0
  198. package/dist/client/assets/perl-DnJAtWNn.js +1 -0
  199. package/dist/client/assets/php-BeY_VEeb.js +1 -0
  200. package/dist/client/assets/pkl-DtSDxyR8.js +1 -0
  201. package/dist/client/assets/plastic-Dd1-4HJb.js +1 -0
  202. package/dist/client/assets/plsql-CgEVu7mV.js +1 -0
  203. package/dist/client/assets/po-BNFx8QMG.js +1 -0
  204. package/dist/client/assets/poimandres-DdZFFINT.js +1 -0
  205. package/dist/client/assets/polar-DcGwqI2v.js +1 -0
  206. package/dist/client/assets/postcss-BgFCg0uM.js +1 -0
  207. package/dist/client/assets/powerquery-BNMZnWRc.js +1 -0
  208. package/dist/client/assets/powershell-CeNh_gMu.js +1 -0
  209. package/dist/client/assets/prisma-C4wKi9Xs.js +1 -0
  210. package/dist/client/assets/prolog-DcNkIfZZ.js +1 -0
  211. package/dist/client/assets/proto-BqsNb_Ru.js +1 -0
  212. package/dist/client/assets/pug-DXhFbVDh.js +1 -0
  213. package/dist/client/assets/puppet-BLvi8DVC.js +1 -0
  214. package/dist/client/assets/purescript-B_tjgp5s.js +1 -0
  215. package/dist/client/assets/python-xLLWlBd0.js +1 -0
  216. package/dist/client/assets/qml-CngzXsz8.js +1 -0
  217. package/dist/client/assets/qmldir-CDe6ORFD.js +1 -0
  218. package/dist/client/assets/qss-CvW7b9vz.js +1 -0
  219. package/dist/client/assets/r-BMmy9apu.js +1 -0
  220. package/dist/client/assets/racket-CA2oKVL1.js +1 -0
  221. package/dist/client/assets/raku-D9dEetfn.js +1 -0
  222. package/dist/client/assets/razor-kIo5DNUk.js +1 -0
  223. package/dist/client/assets/red-Cj1vpJ_n.js +1 -0
  224. package/dist/client/assets/reg-CHsE82Pk.js +1 -0
  225. package/dist/client/assets/regexp-BIa5IayX.js +1 -0
  226. package/dist/client/assets/rel-SUS6CYTF.js +1 -0
  227. package/dist/client/assets/riscv-xyAKa3qa.js +1 -0
  228. package/dist/client/assets/ron-D5BrJbC5.js +1 -0
  229. package/dist/client/assets/rose-pine-Dd0RAvir.js +1 -0
  230. package/dist/client/assets/rose-pine-dawn-CeS_2jlO.js +1 -0
  231. package/dist/client/assets/rose-pine-moon-CQrvtQEF.js +1 -0
  232. package/dist/client/assets/rosmsg-Bie95NPX.js +1 -0
  233. package/dist/client/assets/rst-McWv3WP0.js +1 -0
  234. package/dist/client/assets/ruby-CkenUDKe.js +1 -0
  235. package/dist/client/assets/rust-CAON_J-7.js +1 -0
  236. package/dist/client/assets/sas-Dgn9Yrr5.js +1 -0
  237. package/dist/client/assets/sass-CKkv3rB4.js +1 -0
  238. package/dist/client/assets/scala-BADlfUbE.js +1 -0
  239. package/dist/client/assets/scheme-Bv8vdcS_.js +1 -0
  240. package/dist/client/assets/scss-Tfn9jzBB.js +1 -0
  241. package/dist/client/assets/sdbl-TUdAkzzL.js +1 -0
  242. package/dist/client/assets/shaderlab-C5utLNvK.js +1 -0
  243. package/dist/client/assets/shellscript-vGpgBWOS.js +1 -0
  244. package/dist/client/assets/shellsession-7CA0dOzR.js +1 -0
  245. package/dist/client/assets/slack-dark-BeQrlvP4.js +1 -0
  246. package/dist/client/assets/slack-ochin-DaA1aBiy.js +1 -0
  247. package/dist/client/assets/smalltalk-C1k1DVft.js +1 -0
  248. package/dist/client/assets/snazzy-light-C9Bzvwcg.js +1 -0
  249. package/dist/client/assets/solarized-dark--ZJpQY8O.js +1 -0
  250. package/dist/client/assets/solarized-light-wzNWfjF2.js +1 -0
  251. package/dist/client/assets/solidity-CaEDdWYR.js +1 -0
  252. package/dist/client/assets/soy-DbBURueN.js +1 -0
  253. package/dist/client/assets/sparql-nVt1Q8sD.js +1 -0
  254. package/dist/client/assets/splunk-mpBjmHRA.js +1 -0
  255. package/dist/client/assets/sql-BJGtbEM8.js +1 -0
  256. package/dist/client/assets/ssh-config-DqmSAS3N.js +1 -0
  257. package/dist/client/assets/stata-L0kV9FQT.js +1 -0
  258. package/dist/client/assets/stylus-mNYBrtqL.js +1 -0
  259. package/dist/client/assets/surrealql-C17jcHRl.js +1 -0
  260. package/dist/client/assets/svelte-B5_CmVcu.js +1 -0
  261. package/dist/client/assets/swift-BXoR6L-y.js +1 -0
  262. package/dist/client/assets/synthwave-84-ybvkLGau.js +1 -0
  263. package/dist/client/assets/system-verilog-BnyrpGlO.js +1 -0
  264. package/dist/client/assets/systemd-BBVr_qxh.js +1 -0
  265. package/dist/client/assets/talonscript-l0qUQn2r.js +1 -0
  266. package/dist/client/assets/tasl-BzcMwPTS.js +1 -0
  267. package/dist/client/assets/tcl-CQgtyMkG.js +1 -0
  268. package/dist/client/assets/templ-C5f2EORt.js +1 -0
  269. package/dist/client/assets/terraform-BgPqtSWN.js +1 -0
  270. package/dist/client/assets/tex-DvaBtCMN.js +1 -0
  271. package/dist/client/assets/tokyo-night-BZt2NwCl.js +1 -0
  272. package/dist/client/assets/toml-CpHBCfVl.js +1 -0
  273. package/dist/client/assets/ts-tags-DlZzQdBU.js +1 -0
  274. package/dist/client/assets/tsv-DYxH1-vL.js +1 -0
  275. package/dist/client/assets/tsx-DaLOIju9.js +1 -0
  276. package/dist/client/assets/turtle-DdFFvP5J.js +1 -0
  277. package/dist/client/assets/twig-BB7320dl.js +1 -0
  278. package/dist/client/assets/typescript-D8B-VgXj.js +1 -0
  279. package/dist/client/assets/typespec-CHOxKRtr.js +1 -0
  280. package/dist/client/assets/typst-C0VS9TQm.js +1 -0
  281. package/dist/client/assets/v-CfOPGXPl.js +1 -0
  282. package/dist/client/assets/vala-DYqHmNOK.js +1 -0
  283. package/dist/client/assets/vb-DUBgqZ02.js +1 -0
  284. package/dist/client/assets/verilog-BxybH_AY.js +1 -0
  285. package/dist/client/assets/vesper-BDlBlJR-.js +1 -0
  286. package/dist/client/assets/vhdl-DBoxxi7I.js +1 -0
  287. package/dist/client/assets/viml-C8vROCgw.js +1 -0
  288. package/dist/client/assets/vitesse-black-CUBzmgJa.js +1 -0
  289. package/dist/client/assets/vitesse-dark-COrLBgkv.js +1 -0
  290. package/dist/client/assets/vitesse-light-ThZGgLQK.js +1 -0
  291. package/dist/client/assets/vue-DylGFDrG.js +1 -0
  292. package/dist/client/assets/vue-html-Dt8r3B9y.js +1 -0
  293. package/dist/client/assets/vue-vine-DdN02uhY.js +1 -0
  294. package/dist/client/assets/vyper-D08CaD4o.js +1 -0
  295. package/dist/client/assets/wasm-CoVafRYN.js +1 -0
  296. package/dist/client/assets/wasm-DiIFv9DE.js +1 -0
  297. package/dist/client/assets/wenyan-GlRgAbTB.js +1 -0
  298. package/dist/client/assets/wgsl-BmWpQFqb.js +1 -0
  299. package/dist/client/assets/wikitext-Axug2vPC.js +1 -0
  300. package/dist/client/assets/wit-Dk1fPIaK.js +1 -0
  301. package/dist/client/assets/wolfram-DMhXlmnL.js +1 -0
  302. package/dist/client/assets/xml-CBEuB6I0.js +1 -0
  303. package/dist/client/assets/xsl-CuhlgDL5.js +1 -0
  304. package/dist/client/assets/yaml-Da6ymghi.js +1 -0
  305. package/dist/client/assets/zenscript-x7PXwj2_.js +1 -0
  306. package/dist/client/assets/zig-BlD2NI35.js +1 -0
  307. package/dist/client/index.html +21 -0
  308. package/dist/client/manifest.webmanifest +1 -0
  309. package/dist/client/registerSW.js +1 -0
  310. package/dist/client/sw-push.js +53 -0
  311. package/dist/client/sw.js +1 -0
  312. package/dist/client/workbox-b51dd497.js +1 -0
  313. package/{client/index.html → index.html} +1 -1
  314. package/package.json +62 -14
  315. package/public/icons/icon-192.svg +11 -0
  316. package/public/icons/icon-512.svg +11 -0
  317. package/public/sw-push.js +53 -0
  318. package/{client/src → src/client}/components/analytics/AnalyticsView.tsx +70 -78
  319. package/{client/src → src/client}/components/analytics/ChartCard.tsx +8 -2
  320. package/{client/src → src/client}/components/analytics/QuickStats.tsx +12 -10
  321. package/{client/src → src/client}/components/analytics/charts/ActivityCalendar.tsx +5 -3
  322. package/{client/src → src/client}/components/analytics/charts/CacheEfficiencyChart.tsx +1 -1
  323. package/{client/src → src/client}/components/analytics/charts/ContextUtilizationChart.tsx +33 -25
  324. package/{client/src → src/client}/components/analytics/charts/CostAreaChart.tsx +4 -4
  325. package/{client/src → src/client}/components/analytics/charts/CostDistributionChart.tsx +1 -0
  326. package/{client/src → src/client}/components/analytics/charts/CostDonutChart.tsx +1 -0
  327. package/{client/src → src/client}/components/analytics/charts/CumulativeCostChart.tsx +1 -0
  328. package/{client/src → src/client}/components/analytics/charts/HourlyHeatmap.tsx +5 -3
  329. package/{client/src → src/client}/components/analytics/charts/ProjectRadar.tsx +30 -26
  330. package/{client/src → src/client}/components/analytics/charts/ResponseTimeScatter.tsx +16 -10
  331. package/{client/src → src/client}/components/analytics/charts/SessionBubbleChart.tsx +23 -16
  332. package/{client/src → src/client}/components/analytics/charts/SessionTimeline.tsx +5 -3
  333. package/{client/src → src/client}/components/analytics/charts/TokenFlowChart.tsx +3 -3
  334. package/{client/src → src/client}/components/analytics/charts/ToolSunburst.tsx +26 -23
  335. package/{client/src → src/client}/components/chat/ChatView.tsx +65 -96
  336. package/src/client/components/chat/ElicitationCard.tsx +235 -0
  337. package/{client/src → src/client}/components/chat/Message.tsx +261 -8
  338. package/{client/src → src/client}/components/chat/ModelSelector.tsx +29 -8
  339. package/src/client/components/settings/Appearance.tsx +275 -0
  340. package/{client/src → src/client}/components/settings/BudgetSettings.tsx +6 -2
  341. package/{client/src → src/client}/components/settings/Notifications.tsx +35 -0
  342. package/src/client/components/settings/ThemePreview.tsx +140 -0
  343. package/src/client/components/settings/ThemeWizard.tsx +405 -0
  344. package/{client/src → src/client}/components/sidebar/ProjectRail.tsx +43 -169
  345. package/{client/src → src/client}/components/sidebar/SessionList.tsx +27 -49
  346. package/{client/src → src/client}/components/sidebar/Sidebar.tsx +2 -6
  347. package/src/client/components/sidebar/UserIsland.tsx +282 -0
  348. package/{client/src → src/client}/components/sidebar/UserMenu.tsx +4 -2
  349. package/src/client/components/ui/ContextMenu.tsx +153 -0
  350. package/{client/src → src/client}/components/ui/PopupMenu.tsx +4 -2
  351. package/src/client/components/ui/SaveFooter.tsx +63 -0
  352. package/{client/src → src/client}/components/workspace/TabBar.tsx +17 -64
  353. package/{client/src → src/client}/hooks/useAnalytics.ts +17 -8
  354. package/src/client/hooks/usePushNotifications.ts +92 -0
  355. package/{client/src → src/client}/hooks/useSession.ts +123 -49
  356. package/{client/src → src/client}/hooks/useWebSocket.ts +0 -3
  357. package/src/client/lib/theme-derive.ts +196 -0
  358. package/{client/src → src/client}/stores/analytics.ts +20 -6
  359. package/{client/src → src/client}/stores/session.ts +63 -15
  360. package/{client/src → src/client}/stores/sidebar.ts +3 -1
  361. package/{client/src → src/client}/themes/index.ts +26 -0
  362. package/{server/src → src/server}/analytics/engine.ts +87 -30
  363. package/src/server/assets.ts +45 -0
  364. package/src/server/daemon.ts +547 -0
  365. package/{server/src → src/server}/handlers/analytics.ts +13 -8
  366. package/{server/src → src/server}/handlers/chat.ts +83 -1
  367. package/{server/src → src/server}/handlers/mesh.ts +3 -2
  368. package/{server/src → src/server}/handlers/plugins.ts +10 -13
  369. package/{server/src → src/server}/handlers/session.ts +7 -16
  370. package/{server/src → src/server}/handlers/settings.ts +3 -0
  371. package/{server/src → src/server}/handlers/skills.ts +7 -9
  372. package/src/server/handlers/themes.ts +121 -0
  373. package/{server/src → src/server}/handlers/update.ts +5 -23
  374. package/{server/src → src/server}/index.ts +100 -134
  375. package/{server/src → src/server}/mesh/connector.ts +1 -1
  376. package/{server/src → src/server}/project/context-breakdown.ts +4 -5
  377. package/{server/src → src/server}/project/pty-worker.cjs +1 -1
  378. package/{server/src → src/server}/project/sdk-bridge.ts +526 -428
  379. package/{server/src → src/server}/project/session.ts +117 -42
  380. package/{server/src → src/server}/project/terminal.ts +7 -24
  381. package/src/server/project/warmup.ts +285 -0
  382. package/src/server/push.ts +121 -0
  383. package/src/server/runtime.ts +1 -0
  384. package/src/server/tui.ts +103 -0
  385. package/{server/src → src/server}/update-checker.ts +10 -10
  386. package/{server/src → src/server}/ws/broadcast.ts +8 -8
  387. package/{server/src → src/server}/ws/router.ts +21 -25
  388. package/{shared/src → src/shared}/analytics.ts +1 -0
  389. package/{shared/src → src/shared}/constants.ts +1 -0
  390. package/{shared/src → src/shared}/messages.ts +151 -15
  391. package/{shared/src → src/shared}/models.ts +7 -1
  392. package/tsconfig.json +7 -8
  393. package/{client/vite.config.ts → vite.config.ts} +14 -18
  394. package/.editorconfig +0 -12
  395. package/.github/workflows/ci.yml +0 -81
  396. package/.github/workflows/release.yml +0 -87
  397. package/.impeccable.md +0 -66
  398. package/.releaserc.json +0 -33
  399. package/.serena/memories/code_style_and_conventions.md +0 -35
  400. package/.serena/memories/project_overview.md +0 -51
  401. package/.serena/memories/suggested_commands.md +0 -32
  402. package/.serena/memories/task_completion_checklist.md +0 -15
  403. package/.serena/project.yml +0 -152
  404. package/CLAUDE.md +0 -71
  405. package/CONTRIBUTING.md +0 -93
  406. package/bun.lock +0 -2246
  407. package/bunfig.toml +0 -2
  408. package/client/package.json +0 -43
  409. package/client/src/components/settings/Appearance.tsx +0 -152
  410. package/client/src/components/sidebar/UserIsland.tsx +0 -136
  411. package/client/src/components/ui/SaveFooter.tsx +0 -38
  412. package/client/tsconfig.json +0 -18
  413. package/install.sh +0 -71
  414. package/playwright.config.ts +0 -19
  415. package/scripts/build-binary.ts +0 -157
  416. package/scripts/postinstall.js +0 -31
  417. package/server/package.json +0 -24
  418. package/server/src/_generated/embedded-assets.ts +0 -2
  419. package/server/src/assets.ts +0 -69
  420. package/server/src/daemon.ts +0 -442
  421. package/server/src/runtime.ts +0 -4
  422. package/server/tsconfig.json +0 -20
  423. package/shared/package.json +0 -11
  424. package/shared/tsconfig.json +0 -15
  425. package/tests/accessibility.spec.ts +0 -77
  426. package/tests/keyboard-shortcuts.spec.ts +0 -70
  427. package/tests/message-actions.spec.ts +0 -112
  428. package/tests/onboarding.spec.ts +0 -72
  429. package/tests/session-flow.spec.ts +0 -117
  430. package/tests/session-preview.spec.ts +0 -83
  431. package/themes/amoled.json +0 -20
  432. package/themes/ayu-light.json +0 -9
  433. package/themes/catppuccin-latte.json +0 -9
  434. package/themes/catppuccin-mocha.json +0 -9
  435. package/themes/clay-light.json +0 -10
  436. package/themes/clay.json +0 -10
  437. package/themes/dracula.json +0 -9
  438. package/themes/everforest-light.json +0 -9
  439. package/themes/everforest.json +0 -9
  440. package/themes/github-light.json +0 -9
  441. package/themes/gruvbox-dark.json +0 -9
  442. package/themes/gruvbox-light.json +0 -9
  443. package/themes/monokai.json +0 -9
  444. package/themes/nord-light.json +0 -9
  445. package/themes/nord.json +0 -9
  446. package/themes/one-dark.json +0 -9
  447. package/themes/one-light.json +0 -9
  448. package/themes/rose-pine-dawn.json +0 -9
  449. package/themes/rose-pine.json +0 -9
  450. package/themes/solarized-dark.json +0 -9
  451. package/themes/solarized-light.json +0 -9
  452. package/themes/tokyo-night-light.json +0 -9
  453. package/themes/tokyo-night.json +0 -9
  454. package/tp.js +0 -19
  455. /package/{client/public → dist/client}/icons/icon-192.svg +0 -0
  456. /package/{client/public → dist/client}/icons/icon-512.svg +0 -0
  457. /package/{client/src → src/client}/App.tsx +0 -0
  458. /package/{client/src → src/client}/commands.ts +0 -0
  459. /package/{client/src → src/client}/components/analytics/PeriodSelector.tsx +0 -0
  460. /package/{client/src → src/client}/components/analytics/chartTokens.ts +0 -0
  461. /package/{client/src → src/client}/components/analytics/charts/DailySummaryCards.tsx +0 -0
  462. /package/{client/src → src/client}/components/analytics/charts/NodeFleetOverview.tsx +0 -0
  463. /package/{client/src → src/client}/components/analytics/charts/PermissionBreakdown.tsx +0 -0
  464. /package/{client/src → src/client}/components/analytics/charts/SessionComplexityList.tsx +0 -0
  465. /package/{client/src → src/client}/components/analytics/charts/TokenSankeyChart.tsx +0 -0
  466. /package/{client/src → src/client}/components/analytics/charts/ToolTreemap.tsx +0 -0
  467. /package/{client/src → src/client}/components/auth/PassphrasePrompt.tsx +0 -0
  468. /package/{client/src → src/client}/components/chat/AttachmentChips.tsx +0 -0
  469. /package/{client/src → src/client}/components/chat/ChatInput.tsx +0 -0
  470. /package/{client/src → src/client}/components/chat/CommandPalette.tsx +0 -0
  471. /package/{client/src → src/client}/components/chat/PermissionModeSelector.tsx +0 -0
  472. /package/{client/src → src/client}/components/chat/PromptQuestion.tsx +0 -0
  473. /package/{client/src → src/client}/components/chat/StatusBar.tsx +0 -0
  474. /package/{client/src → src/client}/components/chat/TodoCard.tsx +0 -0
  475. /package/{client/src → src/client}/components/chat/ToolGroup.tsx +0 -0
  476. /package/{client/src → src/client}/components/chat/ToolResultRenderer.tsx +0 -0
  477. /package/{client/src → src/client}/components/chat/VoiceRecorder.tsx +0 -0
  478. /package/{client/src → src/client}/components/chat/toolSummary.ts +0 -0
  479. /package/{client/src → src/client}/components/dashboard/DashboardView.tsx +0 -0
  480. /package/{client/src → src/client}/components/dashboard/ProjectDashboardView.tsx +0 -0
  481. /package/{client/src → src/client}/components/mesh/NodeBadge.tsx +0 -0
  482. /package/{client/src → src/client}/components/mesh/PairingDialog.tsx +0 -0
  483. /package/{client/src → src/client}/components/project-settings/ProjectClaude.tsx +0 -0
  484. /package/{client/src → src/client}/components/project-settings/ProjectEnvironment.tsx +0 -0
  485. /package/{client/src → src/client}/components/project-settings/ProjectGeneral.tsx +0 -0
  486. /package/{client/src → src/client}/components/project-settings/ProjectMcp.tsx +0 -0
  487. /package/{client/src → src/client}/components/project-settings/ProjectMemory.tsx +0 -0
  488. /package/{client/src → src/client}/components/project-settings/ProjectNotifications.tsx +0 -0
  489. /package/{client/src → src/client}/components/project-settings/ProjectPermissions.tsx +0 -0
  490. /package/{client/src → src/client}/components/project-settings/ProjectPlugins.tsx +0 -0
  491. /package/{client/src → src/client}/components/project-settings/ProjectRules.tsx +0 -0
  492. /package/{client/src → src/client}/components/project-settings/ProjectSettingsView.tsx +0 -0
  493. /package/{client/src → src/client}/components/project-settings/ProjectSkills.tsx +0 -0
  494. /package/{client/src → src/client}/components/settings/ClaudeSettings.tsx +0 -0
  495. /package/{client/src → src/client}/components/settings/Editor.tsx +0 -0
  496. /package/{client/src → src/client}/components/settings/Environment.tsx +0 -0
  497. /package/{client/src → src/client}/components/settings/GlobalMcp.tsx +0 -0
  498. /package/{client/src → src/client}/components/settings/GlobalMemory.tsx +0 -0
  499. /package/{client/src → src/client}/components/settings/GlobalPlugins.tsx +0 -0
  500. /package/{client/src → src/client}/components/settings/GlobalRules.tsx +0 -0
  501. /package/{client/src → src/client}/components/settings/GlobalSkills.tsx +0 -0
  502. /package/{client/src → src/client}/components/settings/MeshStatus.tsx +0 -0
  503. /package/{client/src → src/client}/components/settings/SettingsView.tsx +0 -0
  504. /package/{client/src → src/client}/components/settings/SkillMarketplace.tsx +0 -0
  505. /package/{client/src → src/client}/components/settings/mcp-shared.tsx +0 -0
  506. /package/{client/src → src/client}/components/settings/skill-shared.tsx +0 -0
  507. /package/{client/src → src/client}/components/setup/SetupWizard.tsx +0 -0
  508. /package/{client/src → src/client}/components/sidebar/AddProjectModal.tsx +0 -0
  509. /package/{client/src → src/client}/components/sidebar/NodeSettingsModal.tsx +0 -0
  510. /package/{client/src → src/client}/components/sidebar/ProjectDropdown.tsx +0 -0
  511. /package/{client/src → src/client}/components/sidebar/SearchFilter.tsx +0 -0
  512. /package/{client/src → src/client}/components/sidebar/SettingsSidebar.tsx +0 -0
  513. /package/{client/src → src/client}/components/ui/CommandPalette.tsx +0 -0
  514. /package/{client/src → src/client}/components/ui/ErrorBoundary.tsx +0 -0
  515. /package/{client/src → src/client}/components/ui/IconPicker.tsx +0 -0
  516. /package/{client/src → src/client}/components/ui/KeyboardShortcuts.tsx +0 -0
  517. /package/{client/src → src/client}/components/ui/LatticeLogomark.tsx +0 -0
  518. /package/{client/src → src/client}/components/ui/NodeDisconnectedOverlay.tsx +0 -0
  519. /package/{client/src → src/client}/components/ui/Toast.tsx +0 -0
  520. /package/{client/src → src/client}/components/ui/UpdateBanner.tsx +0 -0
  521. /package/{client/src → src/client}/components/ui/UpdatePrompt.tsx +0 -0
  522. /package/{client/src → src/client}/components/workspace/BookmarksView.tsx +0 -0
  523. /package/{client/src → src/client}/components/workspace/FileBrowser.tsx +0 -0
  524. /package/{client/src → src/client}/components/workspace/FileTree.tsx +0 -0
  525. /package/{client/src → src/client}/components/workspace/FileViewer.tsx +0 -0
  526. /package/{client/src → src/client}/components/workspace/NoteCard.tsx +0 -0
  527. /package/{client/src → src/client}/components/workspace/NotesView.tsx +0 -0
  528. /package/{client/src → src/client}/components/workspace/ScheduledTasksView.tsx +0 -0
  529. /package/{client/src → src/client}/components/workspace/SplitPane.tsx +0 -0
  530. /package/{client/src → src/client}/components/workspace/TaskCard.tsx +0 -0
  531. /package/{client/src → src/client}/components/workspace/TaskEditModal.tsx +0 -0
  532. /package/{client/src → src/client}/components/workspace/TerminalInstance.tsx +0 -0
  533. /package/{client/src → src/client}/components/workspace/TerminalView.tsx +0 -0
  534. /package/{client/src → src/client}/components/workspace/WorkspaceView.tsx +0 -0
  535. /package/{client/src → src/client}/hooks/useAttachments.ts +0 -0
  536. /package/{client/src → src/client}/hooks/useBookmarks.ts +0 -0
  537. /package/{client/src → src/client}/hooks/useEditorConfig.ts +0 -0
  538. /package/{client/src → src/client}/hooks/useFocusTrap.ts +0 -0
  539. /package/{client/src → src/client}/hooks/useIdleDetection.ts +0 -0
  540. /package/{client/src → src/client}/hooks/useInstallPrompt.ts +0 -0
  541. /package/{client/src → src/client}/hooks/useMesh.ts +0 -0
  542. /package/{client/src → src/client}/hooks/useNotifications.ts +0 -0
  543. /package/{client/src → src/client}/hooks/useOnline.ts +0 -0
  544. /package/{client/src → src/client}/hooks/useProjectSettings.ts +0 -0
  545. /package/{client/src → src/client}/hooks/useProjects.ts +0 -0
  546. /package/{client/src → src/client}/hooks/useSaveState.ts +0 -0
  547. /package/{client/src → src/client}/hooks/useSidebar.ts +0 -0
  548. /package/{client/src → src/client}/hooks/useSkills.ts +0 -0
  549. /package/{client/src → src/client}/hooks/useSpinnerVerb.ts +0 -0
  550. /package/{client/src → src/client}/hooks/useSwipeDrawer.ts +0 -0
  551. /package/{client/src → src/client}/hooks/useTheme.ts +0 -0
  552. /package/{client/src → src/client}/hooks/useTimeTick.ts +0 -0
  553. /package/{client/src → src/client}/hooks/useVoiceRecorder.ts +0 -0
  554. /package/{client/src → src/client}/hooks/useWorkspace.ts +0 -0
  555. /package/{client/src → src/client}/lib/workspace-url.ts +0 -0
  556. /package/{client/src → src/client}/main.tsx +0 -0
  557. /package/{client/src → src/client}/providers/WebSocketProvider.tsx +0 -0
  558. /package/{client/src → src/client}/router.tsx +0 -0
  559. /package/{client/src → src/client}/stores/bookmarks.ts +0 -0
  560. /package/{client/src → src/client}/stores/mesh.ts +0 -0
  561. /package/{client/src → src/client}/stores/theme.ts +0 -0
  562. /package/{client/src → src/client}/stores/workspace.ts +0 -0
  563. /package/{client/src → src/client}/styles/global.css +0 -0
  564. /package/{client/src → src/client}/styles/theme-vars.css +0 -0
  565. /package/{client/src → src/client}/utils/editorUrl.ts +0 -0
  566. /package/{client/src → src/client}/utils/findDuplicateKeys.ts +0 -0
  567. /package/{client/src → src/client}/utils/formatSessionTitle.ts +0 -0
  568. /package/{client/src → src/client}/vite-env.d.ts +0 -0
  569. /package/{server/src → src/server}/auth/passphrase.ts +0 -0
  570. /package/{server/src → src/server}/config.ts +0 -0
  571. /package/{server/src → src/server}/features/ralph-loop.ts +0 -0
  572. /package/{server/src → src/server}/features/scheduler.ts +0 -0
  573. /package/{server/src → src/server}/features/sticky-notes.ts +0 -0
  574. /package/{server/src → src/server}/handlers/attachment.ts +0 -0
  575. /package/{server/src → src/server}/handlers/bookmarks.ts +0 -0
  576. /package/{server/src → src/server}/handlers/editor.ts +0 -0
  577. /package/{server/src → src/server}/handlers/fs.ts +0 -0
  578. /package/{server/src → src/server}/handlers/loop.ts +0 -0
  579. /package/{server/src → src/server}/handlers/memory.ts +0 -0
  580. /package/{server/src → src/server}/handlers/notes.ts +0 -0
  581. /package/{server/src → src/server}/handlers/project-settings.ts +0 -0
  582. /package/{server/src → src/server}/handlers/scheduler.ts +0 -0
  583. /package/{server/src → src/server}/handlers/terminal.ts +0 -0
  584. /package/{server/src → src/server}/identity.ts +0 -0
  585. /package/{server/src → src/server}/logger.ts +0 -0
  586. /package/{server/src → src/server}/mesh/crypto.ts +0 -0
  587. /package/{server/src → src/server}/mesh/discovery.ts +0 -0
  588. /package/{server/src → src/server}/mesh/pairing.ts +0 -0
  589. /package/{server/src → src/server}/mesh/peers.ts +0 -0
  590. /package/{server/src → src/server}/mesh/proxy.ts +0 -0
  591. /package/{server/src → src/server}/mesh/session-sync.ts +0 -0
  592. /package/{server/src → src/server}/project/bookmarks.ts +0 -0
  593. /package/{server/src → src/server}/project/file-browser.ts +0 -0
  594. /package/{server/src → src/server}/project/project-files.ts +0 -0
  595. /package/{server/src → src/server}/project/registry.ts +0 -0
  596. /package/{server/src → src/server}/tls.ts +0 -0
  597. /package/{server/src → src/server}/ws/server.ts +0 -0
  598. /package/{shared/src → src/shared}/index.ts +0 -0
  599. /package/{shared/src → src/shared}/project-settings.ts +0 -0
@@ -59,76 +59,96 @@ import { DailySummaryCards } from "./charts/DailySummaryCards";
59
59
  import { ProjectRadar } from "./charts/ProjectRadar";
60
60
  import { SessionComplexityList } from "./charts/SessionComplexityList";
61
61
  import { NodeFleetOverview } from "./charts/NodeFleetOverview";
62
+ import type { AnalyticsSectionName } from "@lattice/shared";
62
63
 
63
64
  export function AnalyticsView() {
64
65
  const analytics = useAnalytics();
65
66
  const mesh = useMesh();
66
67
  const nodes = mesh.nodes;
68
+ const hasAnyData = analytics.loadedSections.length > 0;
69
+ const isLoading = analytics.loading;
70
+
71
+ function sectionLoading(name: AnalyticsSectionName): boolean {
72
+ return isLoading && !analytics.loadedSections.includes(name);
73
+ }
67
74
 
68
75
  return (
69
76
  <div className="flex flex-col h-full overflow-hidden bg-base-100 bg-lattice-grid">
70
77
  <div className="flex items-center justify-between px-4 h-11 border-b border-base-300 flex-shrink-0">
71
78
  <div className="flex items-center gap-2.5">
72
79
  <h1 className="text-[13px] font-mono font-bold text-base-content/90">Analytics</h1>
73
- {analytics.loading && analytics.data && (
80
+ {isLoading && hasAnyData && (
74
81
  <span className="w-3.5 h-3.5 border-2 border-base-content/15 border-t-primary/60 rounded-full animate-spin" />
75
82
  )}
76
83
  </div>
77
84
  <PeriodSelector value={analytics.period} onChange={analytics.setPeriod} />
78
85
  </div>
79
86
 
80
- <div className={"flex-1 overflow-y-auto px-3 py-3 sm:px-6 sm:py-4 transition-opacity duration-200 " + (analytics.loading && analytics.data ? "opacity-50" : "opacity-100")}>
81
- {analytics.loading && !analytics.data && (
82
- <div className="flex flex-col gap-4 max-w-[1200px] mx-auto">
83
- <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
84
- {[0, 1, 2, 3].map(function (i) {
85
- return <div key={i} className="h-24 rounded-xl bg-base-content/[0.03] animate-pulse" />;
86
- })}
87
+ <div className="flex-1 overflow-y-auto px-3 py-3 sm:px-6 sm:py-4">
88
+ {analytics.error && (
89
+ <div className="text-center text-error/60 py-20 font-mono text-[13px]">{analytics.error}</div>
90
+ )}
91
+
92
+ {!analytics.error && !isLoading && !hasAnyData && (
93
+ <div className="flex flex-col items-center justify-center py-20 gap-6 max-w-[400px] mx-auto">
94
+ <div className="w-16 h-16 rounded-2xl bg-primary/8 flex items-center justify-center">
95
+ <BarChart3 size={28} className="text-primary/40" />
96
+ </div>
97
+ <div className="text-center">
98
+ <p className="text-[15px] font-mono font-semibold text-base-content/60 mb-2">No analytics data yet</p>
99
+ <p className="text-[13px] text-base-content/30 leading-relaxed">
100
+ Analytics tracks your spending, token usage, cache efficiency, and session patterns across all projects. Start a Claude session to see your first data here.
101
+ </p>
87
102
  </div>
88
- <div className="h-[240px] rounded-xl bg-base-content/[0.03] animate-pulse" />
89
- <div className="grid grid-cols-2 gap-4">
90
- <div className="h-[240px] rounded-xl bg-base-content/[0.03] animate-pulse" />
91
- <div className="h-[240px] rounded-xl bg-base-content/[0.03] animate-pulse" />
103
+ <div className="flex flex-col gap-2 text-[11px] text-base-content/25 font-mono">
104
+ <div className="flex items-center gap-2">
105
+ <div className="w-1 h-1 rounded-full bg-primary/40" />
106
+ <span>Spending trends and cost breakdowns</span>
107
+ </div>
108
+ <div className="flex items-center gap-2">
109
+ <div className="w-1 h-1 rounded-full bg-primary/40" />
110
+ <span>Cache hit rates and response speed</span>
111
+ </div>
112
+ <div className="flex items-center gap-2">
113
+ <div className="w-1 h-1 rounded-full bg-primary/40" />
114
+ <span>Activity patterns and session complexity</span>
115
+ </div>
92
116
  </div>
93
117
  </div>
94
118
  )}
95
119
 
96
- {analytics.error && (
97
- <div className="text-center text-error/60 py-20 font-mono text-[13px]">{analytics.error}</div>
98
- )}
99
-
100
- {analytics.data && (
120
+ {(isLoading || hasAnyData) && (
101
121
  <div className="flex flex-col max-w-[1200px] mx-auto pb-12">
102
122
  <QuickStats />
103
123
 
104
124
  <section className="flex flex-col gap-3 mt-8">
105
125
  <SectionHeader label="Spending" />
106
- <ChartCard title="Spending Over Time">
126
+ <ChartCard title="Spending Over Time" loading={sectionLoading("summary")} skeletonHeight={240}>
107
127
  <ChartErrorBoundary name="CostArea">
108
- <CostAreaChart data={analytics.data.costOverTime} />
128
+ <CostAreaChart data={analytics.data?.costOverTime ?? []} />
109
129
  </ChartErrorBoundary>
110
130
  </ChartCard>
111
131
  <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
112
- <ChartCard title="Spend by Model">
132
+ <ChartCard title="Spend by Model" loading={sectionLoading("spending")}>
113
133
  <ChartErrorBoundary name="CostDonut">
114
- <CostDonutChart modelUsage={analytics.data.modelUsage} totalCost={analytics.data.totalCost} />
134
+ <CostDonutChart modelUsage={analytics.data?.modelUsage ?? []} totalCost={analytics.data?.totalCost ?? 0} />
115
135
  </ChartErrorBoundary>
116
136
  </ChartCard>
117
- <ChartCard title="Running Total">
137
+ <ChartCard title="Running Total" loading={sectionLoading("summary")}>
118
138
  <ChartErrorBoundary name="CumulativeCost">
119
- <CumulativeCostChart data={analytics.data.cumulativeCost} />
139
+ <CumulativeCostChart data={analytics.data?.cumulativeCost ?? []} />
120
140
  </ChartErrorBoundary>
121
141
  </ChartCard>
122
142
  </div>
123
143
  <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
124
- <ChartCard title="Session Cost Ranges">
144
+ <ChartCard title="Session Cost Ranges" loading={sectionLoading("spending")}>
125
145
  <ChartErrorBoundary name="CostDistribution">
126
- <CostDistributionChart data={analytics.data.costDistribution} />
146
+ <CostDistributionChart data={analytics.data?.costDistribution ?? []} />
127
147
  </ChartErrorBoundary>
128
148
  </ChartCard>
129
- <ChartCard title="Cost per Session">
149
+ <ChartCard title="Cost per Session" loading={sectionLoading("spending")}>
130
150
  <ChartErrorBoundary name="SessionBubble">
131
- <SessionBubbleChart data={analytics.data.sessionBubbles} />
151
+ <SessionBubbleChart data={analytics.data?.sessionBubbles ?? []} />
132
152
  </ChartErrorBoundary>
133
153
  </ChartCard>
134
154
  </div>
@@ -136,32 +156,32 @@ export function AnalyticsView() {
136
156
 
137
157
  <section className="flex flex-col gap-3 mt-10">
138
158
  <SectionHeader label="Usage & Speed" />
139
- <ChartCard title="Token Usage Over Time">
159
+ <ChartCard title="Token Usage Over Time" loading={sectionLoading("summary")} skeletonHeight={240}>
140
160
  <ChartErrorBoundary name="TokenFlow">
141
- <TokenFlowChart data={analytics.data.tokensOverTime} />
161
+ <TokenFlowChart data={analytics.data?.tokensOverTime ?? []} />
142
162
  </ChartErrorBoundary>
143
163
  </ChartCard>
144
164
  <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
145
- <ChartCard title="Cache Hit Rate">
165
+ <ChartCard title="Cache Hit Rate" loading={sectionLoading("summary")}>
146
166
  <ChartErrorBoundary name="CacheEfficiency">
147
- <CacheEfficiencyChart data={analytics.data.cacheHitRateOverTime} />
167
+ <CacheEfficiencyChart data={analytics.data?.cacheHitRateOverTime ?? []} />
148
168
  </ChartErrorBoundary>
149
169
  </ChartCard>
150
- <ChartCard title="Response Speed">
170
+ <ChartCard title="Response Speed" loading={sectionLoading("usage")}>
151
171
  <ChartErrorBoundary name="ResponseTime">
152
- <ResponseTimeScatter data={analytics.data.responseTimeData} />
172
+ <ResponseTimeScatter data={analytics.data?.responseTimeData ?? []} />
153
173
  </ChartErrorBoundary>
154
174
  </ChartCard>
155
175
  </div>
156
176
  <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
157
- <ChartCard title="Context Utilization">
177
+ <ChartCard title="Context Utilization" loading={sectionLoading("usage")}>
158
178
  <ChartErrorBoundary name="ContextUtilization">
159
- <ContextUtilizationChart data={analytics.data.contextUtilization} />
179
+ <ContextUtilizationChart data={analytics.data?.contextUtilization ?? []} />
160
180
  </ChartErrorBoundary>
161
181
  </ChartCard>
162
- <ChartCard title="Token Breakdown">
182
+ <ChartCard title="Token Breakdown" loading={sectionLoading("usage")}>
163
183
  <ChartErrorBoundary name="Sankey">
164
- <TokenSankeyChart data={analytics.data.tokenFlowSankey} />
184
+ <TokenSankeyChart data={analytics.data?.tokenFlowSankey ?? { nodes: [], links: [] }} />
165
185
  </ChartErrorBoundary>
166
186
  </ChartCard>
167
187
  </div>
@@ -169,26 +189,26 @@ export function AnalyticsView() {
169
189
 
170
190
  <section className="flex flex-col gap-3 mt-10">
171
191
  <SectionHeader label="Activity" />
172
- <ChartCard title="Activity Calendar">
192
+ <ChartCard title="Activity Calendar" loading={sectionLoading("activity")} skeletonHeight={160}>
173
193
  <ChartErrorBoundary name="Calendar">
174
- <ActivityCalendar data={analytics.data.activityCalendar} />
194
+ <ActivityCalendar data={analytics.data?.activityCalendar ?? []} />
175
195
  </ChartErrorBoundary>
176
196
  </ChartCard>
177
197
  <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
178
- <ChartCard title="Peak Hours">
198
+ <ChartCard title="Peak Hours" loading={sectionLoading("activity")}>
179
199
  <ChartErrorBoundary name="HourlyHeatmap">
180
- <HourlyHeatmap data={analytics.data.hourlyHeatmap} />
200
+ <HourlyHeatmap data={analytics.data?.hourlyHeatmap ?? []} />
181
201
  </ChartErrorBoundary>
182
202
  </ChartCard>
183
- <ChartCard title="Session Timeline">
203
+ <ChartCard title="Session Timeline" loading={sectionLoading("activity")}>
184
204
  <ChartErrorBoundary name="Timeline">
185
- <SessionTimeline data={analytics.data.sessionTimeline} />
205
+ <SessionTimeline data={analytics.data?.sessionTimeline ?? []} />
186
206
  </ChartErrorBoundary>
187
207
  </ChartCard>
188
208
  </div>
189
- <ChartCard title="Daily Summary">
209
+ <ChartCard title="Daily Summary" loading={sectionLoading("activity")} skeletonHeight={120}>
190
210
  <ChartErrorBoundary name="DailySummary">
191
- <DailySummaryCards data={analytics.data.dailySummaries} />
211
+ <DailySummaryCards data={analytics.data?.dailySummaries ?? []} />
192
212
  </ChartErrorBoundary>
193
213
  </ChartCard>
194
214
  </section>
@@ -196,14 +216,14 @@ export function AnalyticsView() {
196
216
  <section className="flex flex-col gap-3 mt-10">
197
217
  <SectionHeader label="Projects" />
198
218
  <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
199
- <ChartCard title="Project Comparison">
219
+ <ChartCard title="Project Comparison" loading={sectionLoading("projects")}>
200
220
  <ChartErrorBoundary name="Radar">
201
- <ProjectRadar data={analytics.data.projectRadar} />
221
+ <ProjectRadar data={analytics.data?.projectRadar ?? []} />
202
222
  </ChartErrorBoundary>
203
223
  </ChartCard>
204
- <ChartCard title="Session Complexity">
224
+ <ChartCard title="Session Complexity" loading={sectionLoading("projects")}>
205
225
  <ChartErrorBoundary name="Complexity">
206
- <SessionComplexityList data={analytics.data.sessionComplexity} />
226
+ <SessionComplexityList data={analytics.data?.sessionComplexity ?? []} />
207
227
  </ChartErrorBoundary>
208
228
  </ChartCard>
209
229
  </div>
@@ -211,41 +231,13 @@ export function AnalyticsView() {
211
231
 
212
232
  <SectionHeader label="Fleet" />
213
233
 
214
- <ChartCard title="Node Fleet">
234
+ <ChartCard title="Node Fleet" loading={false} skeletonHeight={120}>
215
235
  <ChartErrorBoundary name="Fleet">
216
236
  <NodeFleetOverview nodes={nodes} />
217
237
  </ChartErrorBoundary>
218
238
  </ChartCard>
219
239
  </div>
220
240
  )}
221
-
222
- {!analytics.loading && !analytics.error && !analytics.data && (
223
- <div className="flex flex-col items-center justify-center py-20 gap-6 max-w-[400px] mx-auto">
224
- <div className="w-16 h-16 rounded-2xl bg-primary/8 flex items-center justify-center">
225
- <BarChart3 size={28} className="text-primary/40" />
226
- </div>
227
- <div className="text-center">
228
- <p className="text-[15px] font-mono font-semibold text-base-content/60 mb-2">No analytics data yet</p>
229
- <p className="text-[13px] text-base-content/30 leading-relaxed">
230
- Analytics tracks your spending, token usage, cache efficiency, and session patterns across all projects. Start a Claude session to see your first data here.
231
- </p>
232
- </div>
233
- <div className="flex flex-col gap-2 text-[11px] text-base-content/25 font-mono">
234
- <div className="flex items-center gap-2">
235
- <div className="w-1 h-1 rounded-full bg-primary/40" />
236
- <span>Spending trends and cost breakdowns</span>
237
- </div>
238
- <div className="flex items-center gap-2">
239
- <div className="w-1 h-1 rounded-full bg-primary/40" />
240
- <span>Cache hit rates and response speed</span>
241
- </div>
242
- <div className="flex items-center gap-2">
243
- <div className="w-1 h-1 rounded-full bg-primary/40" />
244
- <span>Activity patterns and session complexity</span>
245
- </div>
246
- </div>
247
- </div>
248
- )}
249
241
  </div>
250
242
  </div>
251
243
  );
@@ -24,6 +24,8 @@ interface ChartCardProps {
24
24
  children: ReactNode;
25
25
  className?: string;
26
26
  action?: ReactNode;
27
+ loading?: boolean;
28
+ skeletonHeight?: number;
27
29
  }
28
30
 
29
31
  export function ChartCard(props: ChartCardProps) {
@@ -92,7 +94,9 @@ export function ChartCard(props: ChartCardProps) {
92
94
  </div>
93
95
  </div>
94
96
  <div role="img" aria-label={props.title}>
95
- {props.children}
97
+ {props.loading
98
+ ? <div className="rounded-lg bg-base-content/[0.04] animate-pulse" style={{ height: (props.skeletonHeight ?? 200) + "px" }} />
99
+ : props.children}
96
100
  </div>
97
101
  </>
98
102
  );
@@ -166,7 +170,9 @@ export function ChartCard(props: ChartCardProps) {
166
170
  <div className="flex-1 p-6 overflow-auto min-h-0">
167
171
  <ChartFullscreenContext.Provider value={chartHeight}>
168
172
  <div style={{ height: chartHeight + "px" }}>
169
- {props.children}
173
+ {props.loading
174
+ ? <div className="rounded-lg bg-base-content/[0.04] animate-pulse h-full" />
175
+ : props.children}
170
176
  </div>
171
177
  </ChartFullscreenContext.Provider>
172
178
  </div>
@@ -1,5 +1,6 @@
1
1
  import { LineChart, Line, ResponsiveContainer } from "recharts";
2
- import { useAnalytics } from "../../hooks/useAnalytics";
2
+ import { useStore } from "@tanstack/react-store";
3
+ import { getAnalyticsStore } from "../../stores/analytics";
3
4
  import { getChartColors } from "./chartTokens";
4
5
 
5
6
  function formatTokens(n: number): string {
@@ -31,9 +32,10 @@ function Sparkline({ data, stroke }: SparklineProps) {
31
32
  }
32
33
 
33
34
  export function QuickStats() {
34
- const analytics = useAnalytics();
35
+ const analytics = useStore(getAnalyticsStore(), function (s) { return s; });
36
+ const summaryLoaded = analytics.loadedSections.includes("summary");
35
37
 
36
- if (!analytics.data) {
38
+ if (!summaryLoaded) {
37
39
  return (
38
40
  <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
39
41
  {[0, 1, 2, 3].map(function (i) {
@@ -51,12 +53,12 @@ export function QuickStats() {
51
53
  const d = analytics.data;
52
54
  const colors = getChartColors();
53
55
 
54
- const costSparkData = d.costOverTime.slice(-7).map(function (e: typeof d.costOverTime[number]) { return { v: e.total }; });
55
- const sessionsSparkData = d.sessionsOverTime.slice(-7).map(function (e: typeof d.sessionsOverTime[number]) { return { v: e.count }; });
56
- const tokensSparkData = d.tokensOverTime.slice(-7).map(function (e: typeof d.tokensOverTime[number]) { return { v: e.input + e.output }; });
56
+ const costSparkData = (d.costOverTime ?? []).slice(-7).map(function (e) { return { v: e.total }; });
57
+ const sessionsSparkData = (d.sessionsOverTime ?? []).slice(-7).map(function (e) { return { v: e.count }; });
58
+ const tokensSparkData = (d.tokensOverTime ?? []).slice(-7).map(function (e) { return { v: e.input + e.output }; });
57
59
 
58
- const totalTokens = d.totalTokens.input + d.totalTokens.output;
59
- const cacheHitPct = Math.round(d.cacheHitRate * 100);
60
+ const totalTokens = (d.totalTokens?.input ?? 0) + (d.totalTokens?.output ?? 0);
61
+ const cacheHitPct = Math.round((d.cacheHitRate ?? 0) * 100);
60
62
 
61
63
  return (
62
64
  <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
@@ -69,7 +71,7 @@ export function QuickStats() {
69
71
  </div>
70
72
  )}
71
73
  </div>
72
- <div className="text-[20px] font-mono text-base-content">${d.totalCost.toFixed(2)}</div>
74
+ <div className="text-[20px] font-mono text-base-content">${(d.totalCost ?? 0).toFixed(2)}</div>
73
75
  </div>
74
76
 
75
77
  <div className="bg-base-content/[0.03] rounded-xl p-3.5">
@@ -81,7 +83,7 @@ export function QuickStats() {
81
83
  </div>
82
84
  )}
83
85
  </div>
84
- <div className="text-[20px] font-mono text-base-content">{d.totalSessions}</div>
86
+ <div className="text-[20px] font-mono text-base-content">{d.totalSessions ?? 0}</div>
85
87
  </div>
86
88
 
87
89
  <div className="bg-base-content/[0.03] rounded-xl p-3.5">
@@ -1,4 +1,5 @@
1
1
  import { useState, useRef, useEffect } from "react";
2
+ import { createPortal } from "react-dom";
2
3
  import { getChartColors } from "../chartTokens";
3
4
 
4
5
  interface CalendarDatum {
@@ -185,9 +186,9 @@ export function ActivityCalendar({ data }: ActivityCalendarProps) {
185
186
  })}
186
187
  </svg>
187
188
 
188
- {hover && (
189
+ {hover && createPortal(
189
190
  <div
190
- className="fixed z-50 rounded-lg border border-base-content/8 bg-base-200 px-3 py-2 shadow-lg pointer-events-none"
191
+ className="fixed z-[9999] rounded-lg border border-base-content/8 bg-base-200 px-3 py-2 shadow-lg pointer-events-none"
191
192
  style={{ left: hover.x + 12, top: hover.y - 40 }}
192
193
  >
193
194
  <p className="text-[10px] font-mono text-base-content/50">{hover.datum.date}</p>
@@ -195,7 +196,8 @@ export function ActivityCalendar({ data }: ActivityCalendarProps) {
195
196
  <p><span className="text-base-content/40">sessions </span>{hover.datum.count}</p>
196
197
  <p><span className="text-base-content/40">cost </span>${hover.datum.cost.toFixed(4)}</p>
197
198
  </div>
198
- </div>
199
+ </div>,
200
+ document.body
199
201
  )}
200
202
  </div>
201
203
  );
@@ -49,7 +49,7 @@ export function CacheEfficiencyChart({ data }: CacheEfficiencyChartProps) {
49
49
  <XAxis dataKey="date" tick={getTickStyle()} axisLine={false} tickLine={false} />
50
50
  <YAxis domain={[0, 100]} tick={getTickStyle()} axisLine={false} tickLine={false} tickFormatter={function (v) { return v + "%"; }} />
51
51
  <Tooltip content={<CustomTooltip />} />
52
- <Area type="monotone" dataKey="rate" stroke={colors.success} fill="url(#cacheEffGrad)" strokeWidth={2} />
52
+ <Area type="monotone" dataKey="rate" stroke={colors.success} fill="url(#cacheEffGrad)" strokeWidth={2} isAnimationActive={false} />
53
53
  </AreaChart>
54
54
  </ResponsiveContainer>
55
55
  );
@@ -1,3 +1,4 @@
1
+ import { useMemo } from "react";
1
2
  import {
2
3
  LineChart,
3
4
  Line,
@@ -41,35 +42,41 @@ function CustomTooltip({ active, payload }: { active?: boolean; payload?: Array<
41
42
  export function ContextUtilizationChart({ data }: ContextUtilizationChartProps) {
42
43
  var fullscreenHeight = useChartFullscreen();
43
44
  var colors = getChartColors();
44
- var sessionMap = new Map<string, { title: string; points: Array<{ messageIndex: number; contextPercent: number }> }>();
45
- for (var i = 0; i < data.length; i++) {
46
- var d = data[i];
47
- var entry = sessionMap.get(d.sessionId);
48
- if (!entry) {
49
- entry = { title: d.title, points: [] };
50
- sessionMap.set(d.sessionId, entry);
45
+
46
+ var { sessions, merged } = useMemo(function () {
47
+ var sessionMap = new Map<string, { title: string; points: Array<{ messageIndex: number; contextPercent: number }> }>();
48
+ for (var i = 0; i < data.length; i++) {
49
+ var d = data[i];
50
+ var entry = sessionMap.get(d.sessionId);
51
+ if (!entry) {
52
+ entry = { title: d.title, points: [] };
53
+ sessionMap.set(d.sessionId, entry);
54
+ }
55
+ entry.points.push({ messageIndex: d.messageIndex, contextPercent: d.contextPercent });
51
56
  }
52
- entry.points.push({ messageIndex: d.messageIndex, contextPercent: d.contextPercent });
53
- }
54
57
 
55
- var sessions = Array.from(sessionMap.entries()).slice(0, 5);
58
+ var sessions = Array.from(sessionMap.entries()).slice(0, 5);
59
+
60
+ var maxIndex = 0;
61
+ for (var si = 0; si < sessions.length; si++) {
62
+ var pts = sessions[si][1].points;
63
+ for (var pi = 0; pi < pts.length; pi++) {
64
+ if (pts[pi].messageIndex > maxIndex) maxIndex = pts[pi].messageIndex;
65
+ }
66
+ }
56
67
 
57
- var maxIndex = 0;
58
- sessions.forEach(function (s) {
59
- s[1].points.forEach(function (p) {
60
- if (p.messageIndex > maxIndex) maxIndex = p.messageIndex;
61
- });
62
- });
68
+ var merged: Array<Record<string, number>> = [];
69
+ for (var mi = 0; mi <= maxIndex; mi++) {
70
+ var row: Record<string, number> = { messageIndex: mi };
71
+ for (var sj = 0; sj < sessions.length; sj++) {
72
+ var point = sessions[sj][1].points.find(function (p) { return p.messageIndex === mi; });
73
+ if (point) row[sessions[sj][0]] = point.contextPercent;
74
+ }
75
+ merged.push(row);
76
+ }
63
77
 
64
- var merged: Array<Record<string, number>> = [];
65
- for (var mi = 0; mi <= maxIndex; mi++) {
66
- var row: Record<string, number> = { messageIndex: mi };
67
- sessions.forEach(function (s) {
68
- var point = s[1].points.find(function (p) { return p.messageIndex === mi; });
69
- if (point) row[s[0]] = point.contextPercent;
70
- });
71
- merged.push(row);
72
- }
78
+ return { sessions, merged };
79
+ }, [data]);
73
80
 
74
81
  return (
75
82
  <ResponsiveContainer width="100%" height={fullscreenHeight || 200}>
@@ -89,6 +96,7 @@ export function ContextUtilizationChart({ data }: ContextUtilizationChartProps)
89
96
  strokeWidth={1.5}
90
97
  dot={false}
91
98
  connectNulls
99
+ isAnimationActive={false}
92
100
  />
93
101
  );
94
102
  })}
@@ -69,10 +69,10 @@ export function CostAreaChart({ data }: CostAreaChartProps) {
69
69
  <XAxis dataKey="date" tick={getTickStyle()} axisLine={false} tickLine={false} />
70
70
  <YAxis tick={getTickStyle()} axisLine={false} tickLine={false} tickFormatter={function (v) { return "$" + v.toFixed(2); }} />
71
71
  <Tooltip content={<CustomTooltip />} />
72
- <Area type="monotone" dataKey="opus" stackId="1" stroke={colors.secondary} fill="url(#opusGrad)" strokeWidth={1.5} />
73
- <Area type="monotone" dataKey="sonnet" stackId="1" stroke={colors.primary} fill="url(#sonnetGrad)" strokeWidth={1.5} />
74
- <Area type="monotone" dataKey="haiku" stackId="1" stroke={colors.success} fill="url(#haikuGrad)" strokeWidth={1.5} />
75
- <Area type="monotone" dataKey="other" stackId="1" stroke={colors.warning} fill="url(#otherGrad)" strokeWidth={1.5} />
72
+ <Area type="monotone" dataKey="opus" stackId="1" stroke={colors.secondary} fill="url(#opusGrad)" strokeWidth={1.5} isAnimationActive={false} />
73
+ <Area type="monotone" dataKey="sonnet" stackId="1" stroke={colors.primary} fill="url(#sonnetGrad)" strokeWidth={1.5} isAnimationActive={false} />
74
+ <Area type="monotone" dataKey="haiku" stackId="1" stroke={colors.success} fill="url(#haikuGrad)" strokeWidth={1.5} isAnimationActive={false} />
75
+ <Area type="monotone" dataKey="other" stackId="1" stroke={colors.warning} fill="url(#otherGrad)" strokeWidth={1.5} isAnimationActive={false} />
76
76
  </AreaChart>
77
77
  </ResponsiveContainer>
78
78
  );
@@ -51,6 +51,7 @@ export function CostDistributionChart({ data }: CostDistributionChartProps) {
51
51
  stroke={colors.primary}
52
52
  fill="url(#distGrad)"
53
53
  strokeWidth={2}
54
+ isAnimationActive={false}
54
55
  />
55
56
  </AreaChart>
56
57
  </ResponsiveContainer>
@@ -55,6 +55,7 @@ export function CostDonutChart({ modelUsage, totalCost }: CostDonutChartProps) {
55
55
  paddingAngle={2}
56
56
  startAngle={90}
57
57
  endAngle={-270}
58
+ isAnimationActive={false}
58
59
  >
59
60
  {modelUsage.map(function (entry, index) {
60
61
  return <Cell key={entry.model + index} fill={getModelColor(entry.model)} />;
@@ -51,6 +51,7 @@ export function CumulativeCostChart({ data }: CumulativeCostChartProps) {
51
51
  stroke={colors.primary}
52
52
  fill="url(#cumulativeGrad)"
53
53
  strokeWidth={2}
54
+ isAnimationActive={false}
54
55
  />
55
56
  </AreaChart>
56
57
  </ResponsiveContainer>
@@ -1,4 +1,5 @@
1
1
  import { useState } from "react";
2
+ import { createPortal } from "react-dom";
2
3
  import { getChartColors } from "../chartTokens";
3
4
 
4
5
  interface HeatmapDatum {
@@ -115,16 +116,17 @@ export function HourlyHeatmap({ data }: HourlyHeatmapProps) {
115
116
  })}
116
117
  </svg>
117
118
 
118
- {hover && (
119
+ {hover && createPortal(
119
120
  <div
120
- className="fixed z-50 rounded-lg border border-base-content/8 bg-base-200 px-3 py-2 shadow-lg pointer-events-none"
121
+ className="fixed z-[9999] rounded-lg border border-base-content/8 bg-base-200 px-3 py-2 shadow-lg pointer-events-none"
121
122
  style={{ left: hover.x + 12, top: hover.y - 40 }}
122
123
  >
123
124
  <div className="text-[11px] font-mono text-base-content/70 space-y-0.5">
124
125
  <p><span className="text-base-content/40">{hover.day} </span>{hover.hour}:00</p>
125
126
  <p><span className="text-base-content/40">sessions </span>{hover.count}</p>
126
127
  </div>
127
- </div>
128
+ </div>,
129
+ document.body
128
130
  )}
129
131
  </div>
130
132
  );
@@ -1,3 +1,4 @@
1
+ import { useMemo } from "react";
1
2
  import {
2
3
  RadarChart,
3
4
  Radar,
@@ -50,6 +51,34 @@ function CustomTooltip({ active, payload, label }: { active?: boolean; payload?:
50
51
 
51
52
  export function ProjectRadar({ data }: ProjectRadarProps) {
52
53
  var colors = getChartColors();
54
+
55
+ var { projects, radarData } = useMemo(function () {
56
+ var projects = data.slice(0, 5);
57
+ var normalized = new Map<string, Map<string, number>>();
58
+ for (var ai = 0; ai < AXIS_KEYS.length; ai++) {
59
+ var key = AXIS_KEYS[ai];
60
+ var rawValues = projects.map(function (p) { return p[key] as number; });
61
+ var normValues = normalize(rawValues);
62
+ for (var pi = 0; pi < projects.length; pi++) {
63
+ var projMap = normalized.get(projects[pi].project);
64
+ if (!projMap) {
65
+ projMap = new Map();
66
+ normalized.set(projects[pi].project, projMap);
67
+ }
68
+ projMap.set(key, normValues[pi]);
69
+ }
70
+ }
71
+ var radarData = AXIS_KEYS.map(function (key) {
72
+ var entry: Record<string, string | number> = { axis: AXIS_LABELS[key] };
73
+ for (var pi = 0; pi < projects.length; pi++) {
74
+ var projMap = normalized.get(projects[pi].project);
75
+ entry[projects[pi].project] = projMap ? projMap.get(key) || 0 : 0;
76
+ }
77
+ return entry;
78
+ });
79
+ return { projects, radarData };
80
+ }, [data]);
81
+
53
82
  if (!data || data.length === 0) {
54
83
  return (
55
84
  <div className="flex items-center justify-center h-[250px] text-base-content/25 font-mono text-[11px]">
@@ -58,32 +87,6 @@ export function ProjectRadar({ data }: ProjectRadarProps) {
58
87
  );
59
88
  }
60
89
 
61
- var projects = data.slice(0, 5);
62
-
63
- var normalized = new Map<string, Map<string, number>>();
64
- for (var ai = 0; ai < AXIS_KEYS.length; ai++) {
65
- var key = AXIS_KEYS[ai];
66
- var rawValues = projects.map(function (p) { return p[key] as number; });
67
- var normValues = normalize(rawValues);
68
- for (var pi = 0; pi < projects.length; pi++) {
69
- var projMap = normalized.get(projects[pi].project);
70
- if (!projMap) {
71
- projMap = new Map();
72
- normalized.set(projects[pi].project, projMap);
73
- }
74
- projMap.set(key, normValues[pi]);
75
- }
76
- }
77
-
78
- var radarData = AXIS_KEYS.map(function (key) {
79
- var entry: Record<string, string | number> = { axis: AXIS_LABELS[key] };
80
- for (var pi = 0; pi < projects.length; pi++) {
81
- var projMap = normalized.get(projects[pi].project);
82
- entry[projects[pi].project] = projMap ? projMap.get(key) || 0 : 0;
83
- }
84
- return entry;
85
- });
86
-
87
90
  return (
88
91
  <ResponsiveContainer width="100%" height={280}>
89
92
  <RadarChart data={radarData} margin={{ top: 10, right: 30, bottom: 10, left: 30 }}>
@@ -108,6 +111,7 @@ export function ProjectRadar({ data }: ProjectRadarProps) {
108
111
  fill={colors.palette[index % colors.palette.length]}
109
112
  fillOpacity={0.1}
110
113
  strokeWidth={1.5}
114
+ isAnimationActive={false}
111
115
  />
112
116
  );
113
117
  })}