cognova 0.1.9 → 0.2.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 (299) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{B4LjQa2N.js → 4MiwzAAt.js} +2 -2
  3. package/.output/public/_nuxt/{BZZeOWzQ.js → 5ZXA0Ckq.js} +1 -1
  4. package/.output/public/_nuxt/{B194okoV.js → 9IQmsEjr.js} +1 -1
  5. package/.output/public/_nuxt/{DQ_ZoW_9.js → 9QnH0xQM.js} +1 -1
  6. package/.output/public/_nuxt/{CF0HGIV6.js → B1X4Bzcy.js} +1 -1
  7. package/.output/public/_nuxt/{D9lowtoI.js → B3y_Qqox.js} +1 -1
  8. package/.output/public/_nuxt/{BB1R_SaV.js → B6S_ob86.js} +1 -1
  9. package/.output/public/_nuxt/{DVf1IpSh.js → BAIz-dEB.js} +1 -1
  10. package/.output/public/_nuxt/{CNFNMRY1.js → BCtfQCzC.js} +1 -1
  11. package/.output/public/_nuxt/BIIJhjQO.js +1 -0
  12. package/.output/public/_nuxt/BIckl6wA.js +1 -0
  13. package/.output/public/_nuxt/{Biy6boRV.js → BJ3o57WW.js} +1 -1
  14. package/.output/public/_nuxt/{B5rIsDOv.js → BNetzZzF.js} +1 -1
  15. package/.output/public/_nuxt/{DFXLcgxL.js → BOj6t-oo.js} +1 -1
  16. package/.output/public/_nuxt/{BDUpLPg_.js → BS0ofHJK.js} +1 -1
  17. package/.output/public/_nuxt/{DIdcflWi.js → BWhMnjID.js} +1 -1
  18. package/.output/public/_nuxt/{CExLOuIW.js → BYjadNrw.js} +1 -1
  19. package/.output/public/_nuxt/{C8ytOrRD.js → BZXMQuYP.js} +1 -1
  20. package/.output/public/_nuxt/{Ddih3UKd.js → B_3_hrpn.js} +1 -1
  21. package/.output/public/_nuxt/{CxSyRXlk.js → BaBZjmMC.js} +1 -1
  22. package/.output/public/_nuxt/BaMqDm5u.js +1 -0
  23. package/.output/public/_nuxt/BasgsT_S.js +1 -0
  24. package/.output/public/_nuxt/{Cehzuz52.js → BffWCM73.js} +1 -1
  25. package/.output/public/_nuxt/{Dh0BcDEI.js → BhzMoffi.js} +1 -1
  26. package/.output/public/_nuxt/{DmV68Eyp.js → BjjCvHLT.js} +1 -1
  27. package/.output/public/_nuxt/{nzAH3Wk0.js → BlAZO7nq.js} +1 -1
  28. package/.output/public/_nuxt/{BRPJdy3u.js → BlhFigLL.js} +1 -1
  29. package/.output/public/_nuxt/{CfTFjEuh.js → Bm9LyG4F.js} +1 -1
  30. package/.output/public/_nuxt/BoIxv-gM.js +1 -0
  31. package/.output/public/_nuxt/{BslL2E8V.js → BqKFIuRj.js} +1 -1
  32. package/.output/public/_nuxt/Br19oYkq.js +1 -0
  33. package/.output/public/_nuxt/{PtGESE-F.js → BrNqhp1a.js} +3 -3
  34. package/.output/public/_nuxt/{FvV9sv7q.js → BsEZoHd1.js} +1 -1
  35. package/.output/public/_nuxt/{BaPPQtFe.js → BxXOsXrM.js} +10 -10
  36. package/.output/public/_nuxt/BzOqrmGa.js +7 -0
  37. package/.output/public/_nuxt/{BNAsyazX.js → C0JKNMDO.js} +1 -1
  38. package/.output/public/_nuxt/C0kh_F7v.js +1 -0
  39. package/.output/public/_nuxt/{4Ew5YctE.js → C3FxIITy.js} +1 -1
  40. package/.output/public/_nuxt/{DnToOWVx.js → C4pxqdgg.js} +1 -1
  41. package/.output/public/_nuxt/{C5Ue4WbD.js → C61KgSco.js} +1 -1
  42. package/.output/public/_nuxt/{DcMvYcFq.js → C69W7k2j.js} +1 -1
  43. package/.output/public/_nuxt/{BnnFvWzv.js → C6RC3lA1.js} +1 -1
  44. package/.output/public/_nuxt/{DBENYi9d.js → C6aqGHu1.js} +1 -1
  45. package/.output/public/_nuxt/{YldWqMAh.js → CJUdYEdO.js} +1 -1
  46. package/.output/public/_nuxt/{BPAM-iC7.js → CKkC3Ptm.js} +1 -1
  47. package/.output/public/_nuxt/{CTXhFIUN.js → CNnJrDvu.js} +1 -1
  48. package/.output/public/_nuxt/{BwH2E0-a.js → CVJQGP1Q.js} +1 -1
  49. package/.output/public/_nuxt/{q0vhMpUB.js → CVgTJeSq.js} +1 -1
  50. package/.output/public/_nuxt/CWMUi89H.js +1 -0
  51. package/.output/public/_nuxt/{BU9VyOEC.js → CYP_MLH8.js} +1 -1
  52. package/.output/public/_nuxt/{76CHU1js.js → C_BdYLzz.js} +1 -1
  53. package/.output/public/_nuxt/{BQbnVFXA.js → Cdt3I3Go.js} +1 -1
  54. package/.output/public/_nuxt/Cdu2qGgq.js +1 -0
  55. package/.output/public/_nuxt/{ChMIRIq6.js → CeIVm4A3.js} +1 -1
  56. package/.output/public/_nuxt/CeIu7z4p.js +1 -0
  57. package/.output/public/_nuxt/{CZZw0T2a.js → Ci7UEZQh.js} +1 -1
  58. package/.output/public/_nuxt/{BP_jQhKs.js → CihWZmJe.js} +2 -2
  59. package/.output/public/_nuxt/{Bluqlt6l.js → CitkKxhw.js} +1 -1
  60. package/.output/public/_nuxt/{DIM73BjE.js → CmzH6R-N.js} +2 -2
  61. package/.output/public/_nuxt/{CD5hHJBM.js → Cp2MA0cm.js} +1 -1
  62. package/.output/public/_nuxt/{DflBkWfa.js → CqU2XbzO.js} +1 -1
  63. package/.output/public/_nuxt/{Ccc8OoR8.js → Cqy_L_ip.js} +1 -1
  64. package/.output/public/_nuxt/Cr8ixbr1.js +1 -0
  65. package/.output/public/_nuxt/{DdLGO0wP.js → CsJ9KhQ4.js} +1 -1
  66. package/.output/public/_nuxt/{mHNfVoS0.js → CtYFj7k1.js} +1 -1
  67. package/.output/public/_nuxt/{DIBimEIe.js → CtchsY6e.js} +1 -1
  68. package/.output/public/_nuxt/{BboG47Wz.js → Cvp7FI3T.js} +1 -1
  69. package/.output/public/_nuxt/CxuZBC8n.js +70 -0
  70. package/.output/public/_nuxt/D2689qk4.js +1 -0
  71. package/.output/public/_nuxt/{CWWmC6Y7.js → D31L7Ks6.js} +1 -1
  72. package/.output/public/_nuxt/{JxSV3wOO.js → D3RiUGdz.js} +1 -1
  73. package/.output/public/_nuxt/{C1tYtAeV.js → D3e44mCL.js} +1 -1
  74. package/.output/public/_nuxt/{BTWyDDBM.js → D6t3dcTl.js} +1 -1
  75. package/.output/public/_nuxt/{DpLjEbYb.js → DAQhmSv4.js} +1 -1
  76. package/.output/public/_nuxt/{BnwR3LQL.js → DB359q8R.js} +1 -1
  77. package/.output/public/_nuxt/{jCKYMNtT.js → DCzfkCGa.js} +1 -1
  78. package/.output/public/_nuxt/{BXWm1qrj.js → DG-T44jj.js} +1 -1
  79. package/.output/public/_nuxt/{BBygTbuF.js → DGX0tzL8.js} +1 -1
  80. package/.output/public/_nuxt/DHG66LPS.js +1 -0
  81. package/.output/public/_nuxt/{jBqB49XU.js → DHKLCQRG.js} +1 -1
  82. package/.output/public/_nuxt/{BDw-JoCx.js → DIoI0uJm.js} +1 -1
  83. package/.output/public/_nuxt/{DOQA5CEF.js → DJ5V-y_x.js} +1 -1
  84. package/.output/public/_nuxt/{BGaNWD0s.js → DJMS2og1.js} +1 -1
  85. package/.output/public/_nuxt/{UmgHYYVi.js → DJjDvbZE.js} +1 -1
  86. package/.output/public/_nuxt/{DdtX5kio.js → DK9jxJ0g.js} +1 -1
  87. package/.output/public/_nuxt/{Cc6GlQCO.js → DKZxeXDQ.js} +1 -1
  88. package/.output/public/_nuxt/{Tp-9mt9j.js → DLETdGFL.js} +1 -1
  89. package/.output/public/_nuxt/DOICd-Ld.js +1 -0
  90. package/.output/public/_nuxt/DPEcH-gi.js +65 -0
  91. package/.output/public/_nuxt/{CVNY6Bll.js → DSRrg8JT.js} +1 -1
  92. package/.output/public/_nuxt/{Sm7TJN7_.js → DTDgHTuh.js} +2 -2
  93. package/.output/public/_nuxt/{DeGKAWfY.js → D_3Rq1BS.js} +1 -1
  94. package/.output/public/_nuxt/{BvnL4Jyv.js → Daz4MeL6.js} +1 -1
  95. package/.output/public/_nuxt/{Dyd3g9po.js → Db2v8O7O.js} +1 -1
  96. package/.output/public/_nuxt/{D0FBwEzN.js → Db8-_gO7.js} +1 -1
  97. package/.output/public/_nuxt/{Cv4Qjbqk.js → DfQu3kEw.js} +1 -1
  98. package/.output/public/_nuxt/{c-RGQpsW.js → DgV-EDJ9.js} +1 -1
  99. package/.output/public/_nuxt/{CSF2cTe9.js → DnjGH3SQ.js} +1 -1
  100. package/.output/public/_nuxt/Dp2X5R2m.js +1 -0
  101. package/.output/public/_nuxt/DqB723Z0.js +1 -0
  102. package/.output/public/_nuxt/{DhRePYUI.js → DyRelyfs.js} +1 -1
  103. package/.output/public/_nuxt/{DZiAD6YN.js → Dy_Cq5LQ.js} +1 -1
  104. package/.output/public/_nuxt/{DWQMV4k2.js → DznawRFW.js} +1 -1
  105. package/.output/public/_nuxt/EuOqK1A6.js +1 -0
  106. package/.output/public/_nuxt/{BVZHIuu-.js → FNC8XZTk.js} +1 -1
  107. package/.output/public/_nuxt/{Dsk8JtTw.js → Fukkqjkf.js} +1 -1
  108. package/.output/public/_nuxt/{DNpdNXnv.js → FvlxxmNk.js} +2 -2
  109. package/.output/public/_nuxt/{zt0Txq93.js → IRSbVPIu.js} +1 -1
  110. package/.output/public/_nuxt/{T_w6A2Zo.js → JJ3634gV.js} +9 -9
  111. package/.output/public/_nuxt/{6Tt_Iaya.js → Jez9DHn7.js} +1 -1
  112. package/.output/public/_nuxt/{Cr7nQmYw.js → KKK6HVeG.js} +1 -1
  113. package/.output/public/_nuxt/{BJPw54Qz.js → Lwdv_RKd.js} +1 -1
  114. package/.output/public/_nuxt/{WqUIRM3G.js → Nb2jBtYT.js} +1 -1
  115. package/.output/public/_nuxt/Q8Ps7oN5.js +1 -0
  116. package/.output/public/_nuxt/SXTDhzp6.js +1 -0
  117. package/.output/public/_nuxt/{rfcePMfo.js → Sg2Lwc46.js} +1 -1
  118. package/.output/public/_nuxt/{gEpwc5gO.js → YuTZB7sD.js} +1 -1
  119. package/.output/public/_nuxt/{B2OKrc4G.js → _CYZi8HN.js} +1 -1
  120. package/.output/public/_nuxt/_J_7XIn-.js +1 -0
  121. package/.output/public/_nuxt/builds/latest.json +1 -1
  122. package/.output/public/_nuxt/builds/meta/a1e9100c-1a4f-4f7e-bb53-9dbe0d07effb.json +1 -0
  123. package/.output/public/_nuxt/{Bwx_Kl-4.js → cABRLVee.js} +1 -1
  124. package/.output/public/_nuxt/{DPuJYSUH.js → eko-0FUm.js} +1 -1
  125. package/.output/public/_nuxt/entry.CGxIBGAf.css +1 -0
  126. package/.output/public/_nuxt/{TQOIXkvr.js → g20UHUCv.js} +1 -1
  127. package/.output/public/_nuxt/{zOs8gUGl.js → gBC9k4Qj.js} +1 -1
  128. package/.output/public/_nuxt/{CJ3DQEW9.js → ghuJ76mD.js} +1 -1
  129. package/.output/public/_nuxt/{S6GTaxiQ.js → iBGCpHdw.js} +1 -1
  130. package/.output/public/_nuxt/{VGlRzjk3.js → inmzPrjz.js} +1 -1
  131. package/.output/public/_nuxt/{CCkumwhk.js → m5kGCDpI.js} +4 -4
  132. package/.output/public/_nuxt/{CXkbkhUa.js → nIU2F7ia.js} +3 -3
  133. package/.output/public/_nuxt/oIX-ZDN6.js +1 -0
  134. package/.output/public/_nuxt/{TsIha0iy.js → pcUI-zuY.js} +1 -1
  135. package/.output/public/_nuxt/{BN_2zhBR.js → sf57orEk.js} +1 -1
  136. package/.output/public/_nuxt/usage.vakN1lvi.css +1 -0
  137. package/.output/public/_nuxt/{DHYn0MnY.js → wCGVE8_e.js} +1 -1
  138. package/.output/public/_nuxt/{DMkXE4gH.js → xuzLdW-o.js} +1 -1
  139. package/.output/public/_nuxt/{DdoFnl6e.js → yNrp2XvX.js} +1 -1
  140. package/.output/public/_nuxt/{4hIPJQLp.js → yuf23kh9.js} +1 -1
  141. package/.output/server/chunks/build/CodeIcon-CWD5HcV7.mjs +1 -1
  142. package/.output/server/chunks/build/DropdownMenu-BBrV9nXz.mjs +1 -1
  143. package/.output/server/chunks/build/EditorToolbar-DIfb5arC.mjs +1 -1
  144. package/.output/server/chunks/build/Img-CWLmvN1t.mjs +1 -1
  145. package/.output/server/chunks/build/MDC-Dx0YPDhe.mjs +1 -1
  146. package/.output/server/chunks/build/Select-BB1oLrCD.mjs +1 -1
  147. package/.output/server/chunks/build/SelectMenu-DPssg6zD.mjs +1 -1
  148. package/.output/server/chunks/build/Table-DCwTlhCj.mjs +1 -1
  149. package/.output/server/chunks/build/Tooltip-TRyl6dje.mjs +1 -1
  150. package/.output/server/chunks/build/{_uuid_-CQEMsF1D.mjs → _uuid_-0UgdUhfY.mjs} +8 -7
  151. package/.output/server/chunks/build/{_uuid_-CQEMsF1D.mjs.map → _uuid_-0UgdUhfY.mjs.map} +1 -1
  152. package/.output/server/chunks/build/chat-CZMiB68R.mjs.map +1 -1
  153. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  154. package/.output/server/chunks/build/cookie-C_iulBi6.mjs +1 -1
  155. package/.output/server/chunks/build/{dashboard-24rCroiO.mjs → dashboard-CpMVYnDV.mjs} +13 -6
  156. package/.output/server/chunks/build/{dashboard-24rCroiO.mjs.map → dashboard-CpMVYnDV.mjs.map} +1 -1
  157. package/.output/server/chunks/build/dashboard-YEscLBQN.mjs +1109 -0
  158. package/.output/server/chunks/build/dashboard-YEscLBQN.mjs.map +1 -0
  159. package/.output/server/chunks/build/{docs-DOGZUctm.mjs → docs-Dk2JnYq3.mjs} +8 -7
  160. package/.output/server/chunks/build/{docs-DOGZUctm.mjs.map → docs-Dk2JnYq3.mjs.map} +1 -1
  161. package/.output/server/chunks/build/fetch-BB7Qzkwe.mjs +1 -1
  162. package/.output/server/chunks/build/{hooks-CuyNIRFI.mjs → hooks-DP8WoUPS.mjs} +2 -2
  163. package/.output/server/chunks/build/{hooks-CuyNIRFI.mjs.map → hooks-DP8WoUPS.mjs.map} +1 -1
  164. package/.output/server/chunks/build/{index-BZI-Mj1-.mjs → index-Ba_bPJgk.mjs} +2 -2
  165. package/.output/server/chunks/build/{index-BZI-Mj1-.mjs.map → index-Ba_bPJgk.mjs.map} +1 -1
  166. package/.output/server/chunks/build/index-CxDxc9fm.mjs +1 -1
  167. package/.output/server/chunks/build/server.mjs +26 -17
  168. package/.output/server/chunks/build/server.mjs.map +1 -1
  169. package/.output/server/chunks/build/settings-DdkKCJ00.mjs +1 -1
  170. package/.output/server/chunks/build/styles.mjs +2 -2
  171. package/.output/server/chunks/build/{tasks-DR55Wjpi.mjs → tasks-DiOi1HG_.mjs} +2 -2
  172. package/.output/server/chunks/build/{tasks-DR55Wjpi.mjs.map → tasks-DiOi1HG_.mjs.map} +1 -1
  173. package/.output/server/chunks/build/usage-H_mcd_fz.mjs +1578 -0
  174. package/.output/server/chunks/build/usage-H_mcd_fz.mjs.map +1 -0
  175. package/.output/server/chunks/build/{CodeEditorFallback-DfYly7f5.mjs → useCopyToClipboard-vi6FYyyZ.mjs} +29 -2
  176. package/.output/server/chunks/build/useCopyToClipboard-vi6FYyyZ.mjs.map +1 -0
  177. package/.output/server/chunks/build/useNotificationBus-BG5JNQf1.mjs +1 -1
  178. package/.output/server/chunks/build/{usePreferences-CUvZsOq5.mjs → usePreferences-CzC8fRzd.mjs} +7 -1
  179. package/.output/server/chunks/build/usePreferences-CzC8fRzd.mjs.map +1 -0
  180. package/.output/server/chunks/build/view-Dc8mvzCB.mjs +1 -1
  181. package/.output/server/chunks/nitro/nitro.mjs +884 -818
  182. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  183. package/.output/server/chunks/routes/_ws/chat.mjs +18 -4
  184. package/.output/server/chunks/routes/_ws/chat.mjs.map +1 -1
  185. package/.output/server/chunks/routes/api/dashboard/overview.get.mjs +149 -0
  186. package/.output/server/chunks/routes/api/dashboard/overview.get.mjs.map +1 -0
  187. package/.output/server/chunks/routes/api/documents/_id/public.get.mjs +1 -1
  188. package/.output/server/chunks/routes/api/documents/_id/restore.post.mjs +1 -1
  189. package/.output/server/chunks/routes/api/documents/by-path.post.mjs +1 -1
  190. package/.output/server/chunks/routes/api/documents/index.delete.mjs +1 -1
  191. package/.output/server/chunks/routes/api/documents/index.put.mjs +1 -1
  192. package/.output/server/chunks/routes/api/fs/delete.post.mjs +1 -1
  193. package/.output/server/chunks/routes/api/fs/list.get.mjs +1 -1
  194. package/.output/server/chunks/routes/api/fs/mkdir.post.mjs +1 -1
  195. package/.output/server/chunks/routes/api/fs/move.post.mjs +1 -1
  196. package/.output/server/chunks/routes/api/fs/read.post.mjs +1 -1
  197. package/.output/server/chunks/routes/api/fs/rename.post.mjs +1 -1
  198. package/.output/server/chunks/routes/api/fs/write.post.mjs +1 -1
  199. package/.output/server/chunks/routes/api/health.get.mjs +1 -1
  200. package/.output/server/chunks/routes/api/home.get.mjs +1 -1
  201. package/.output/server/chunks/routes/api/hooks/index.get.mjs +1 -1
  202. package/.output/server/chunks/routes/api/hooks/index.post.mjs +1 -1
  203. package/.output/server/chunks/routes/api/hooks/stats.get.mjs +1 -1
  204. package/.output/server/chunks/routes/api/index.get3.mjs +1 -1
  205. package/.output/server/chunks/routes/api/index.get4.mjs +1 -1
  206. package/.output/server/chunks/routes/api/index.get5.mjs +1 -1
  207. package/.output/server/chunks/routes/api/index.get6.mjs +1 -1
  208. package/.output/server/chunks/routes/api/index.get7.mjs +1 -1
  209. package/.output/server/chunks/routes/api/index.get8.mjs +82 -0
  210. package/.output/server/chunks/routes/api/index.get8.mjs.map +1 -0
  211. package/.output/server/chunks/routes/api/index.post2.mjs +1 -1
  212. package/.output/server/chunks/routes/api/index.post3.mjs +1 -1
  213. package/.output/server/chunks/routes/api/index.post4.mjs +1 -1
  214. package/.output/server/chunks/routes/api/index.put.mjs +1 -1
  215. package/.output/server/chunks/routes/api/memory/_id_.delete.mjs +1 -1
  216. package/.output/server/chunks/routes/api/memory/context.get.mjs +1 -1
  217. package/.output/server/chunks/routes/api/memory/extract.post.mjs +20 -1
  218. package/.output/server/chunks/routes/api/memory/extract.post.mjs.map +1 -1
  219. package/.output/server/chunks/routes/api/memory/search.get.mjs +1 -1
  220. package/.output/server/chunks/routes/api/memory/store.post.mjs +1 -1
  221. package/.output/server/chunks/routes/api/projects/index.delete.mjs +1 -1
  222. package/.output/server/chunks/routes/api/projects/index.get.mjs +1 -1
  223. package/.output/server/chunks/routes/api/projects/index.put.mjs +1 -1
  224. package/.output/server/chunks/routes/api/secrets/_key_.delete.mjs +1 -1
  225. package/.output/server/chunks/routes/api/secrets/_key_.get.mjs +1 -1
  226. package/.output/server/chunks/routes/api/secrets/_key_.put.mjs +1 -1
  227. package/.output/server/chunks/routes/api/tasks/_id/restore.post.mjs +1 -1
  228. package/.output/server/chunks/routes/api/tasks/index.delete.mjs +1 -1
  229. package/.output/server/chunks/routes/api/tasks/index.put.mjs +1 -1
  230. package/.output/server/chunks/routes/api/tasks/tags.get.mjs +1 -1
  231. package/.output/server/chunks/routes/api/usage/stats.get.mjs +130 -0
  232. package/.output/server/chunks/routes/api/usage/stats.get.mjs.map +1 -0
  233. package/.output/server/chunks/routes/api/user/email.patch.mjs +1 -1
  234. package/.output/server/chunks/routes/notifications.mjs +1 -1
  235. package/.output/server/chunks/routes/renderer.mjs +1 -1
  236. package/.output/server/chunks/routes/terminal.mjs +1 -1
  237. package/.output/server/index.mjs +1 -1
  238. package/.output/server/package.json +1 -1
  239. package/app/components/dashboard/RecentChats.vue +93 -0
  240. package/app/components/dashboard/RecentDocs.vue +108 -0
  241. package/app/components/dashboard/StatCards.vue +82 -0
  242. package/app/components/dashboard/UpcomingTasks.vue +119 -0
  243. package/app/components/dashboard/UsageSummary.vue +94 -0
  244. package/app/components/editor/DocumentEditor.vue +5 -3
  245. package/app/components/usage/UsageCostChart.client.vue +174 -0
  246. package/app/components/usage/UsageCostChart.server.vue +22 -0
  247. package/app/components/usage/UsageRecordsTable.vue +249 -0
  248. package/app/components/usage/UsageSourceDonut.client.vue +93 -0
  249. package/app/components/usage/UsageSourceDonut.server.vue +21 -0
  250. package/app/components/usage/UsageStatsCards.vue +101 -0
  251. package/app/components/usage/UsageTopConsumers.vue +89 -0
  252. package/app/composables/useCopyToClipboard.ts +37 -0
  253. package/app/composables/usePreferences.ts +10 -0
  254. package/app/layouts/dashboard.vue +8 -1
  255. package/app/pages/chat.vue +11 -1
  256. package/app/pages/dashboard.vue +65 -64
  257. package/app/pages/usage.vue +130 -0
  258. package/app/pages/view/[uuid].vue +4 -3
  259. package/package.json +1 -1
  260. package/server/api/dashboard/overview.get.ts +133 -0
  261. package/server/api/usage/index.get.ts +69 -0
  262. package/server/api/usage/stats.get.ts +127 -0
  263. package/server/db/schema.ts +17 -0
  264. package/server/drizzle/migrations/0011_tearful_johnny_storm.sql +12 -0
  265. package/server/drizzle/migrations/meta/0011_snapshot.json +1634 -0
  266. package/server/drizzle/migrations/meta/_journal.json +7 -0
  267. package/server/routes/_ws/chat.ts +29 -2
  268. package/server/services/agent-executor.ts +13 -0
  269. package/server/services/memory-extractor.ts +25 -0
  270. package/server/utils/log-token-usage.ts +22 -0
  271. package/shared/types/index.ts +81 -0
  272. package/.output/public/_nuxt/B34UfOg4.js +0 -1
  273. package/.output/public/_nuxt/B3DmiwBX.js +0 -1
  274. package/.output/public/_nuxt/BESViHC6.js +0 -1
  275. package/.output/public/_nuxt/BIm_buQF.js +0 -1
  276. package/.output/public/_nuxt/BMh-dHBK.js +0 -1
  277. package/.output/public/_nuxt/Bkv1Ouue.js +0 -1
  278. package/.output/public/_nuxt/C4i10ReQ.js +0 -1
  279. package/.output/public/_nuxt/C5euqjeX.js +0 -1
  280. package/.output/public/_nuxt/C9hy_rtV.js +0 -1
  281. package/.output/public/_nuxt/CWJhKIyp.js +0 -1
  282. package/.output/public/_nuxt/Ck24Z-8o.js +0 -1
  283. package/.output/public/_nuxt/D1JmZKz7.js +0 -1
  284. package/.output/public/_nuxt/D6xvQUYG.js +0 -1
  285. package/.output/public/_nuxt/DGTbw5AQ.js +0 -1
  286. package/.output/public/_nuxt/Da8Xd1w6.js +0 -1
  287. package/.output/public/_nuxt/DamUHI17.js +0 -1
  288. package/.output/public/_nuxt/DoIiMqKa.js +0 -76
  289. package/.output/public/_nuxt/builds/meta/75ff59f2-0860-4bfc-a288-c670397cae5c.json +0 -1
  290. package/.output/public/_nuxt/entry.tLLAvqs1.css +0 -1
  291. package/.output/public/_nuxt/iJ4KRInq.js +0 -1
  292. package/.output/public/_nuxt/mSr5c6cB.js +0 -1
  293. package/.output/public/_nuxt/r8g_V5AH.js +0 -1
  294. package/.output/public/_nuxt/rZmMQHiC.js +0 -1
  295. package/.output/server/chunks/build/CodeEditorFallback-DfYly7f5.mjs.map +0 -1
  296. package/.output/server/chunks/build/dashboard-DtbGchTa.mjs +0 -277
  297. package/.output/server/chunks/build/dashboard-DtbGchTa.mjs.map +0 -1
  298. package/.output/server/chunks/build/usePreferences-CUvZsOq5.mjs.map +0 -1
  299. /package/.output/public/_nuxt/{language-detection.Be_IvFWy.css → useCopyToClipboard.Be_IvFWy.css} +0 -0
@@ -0,0 +1,93 @@
1
+ <script setup lang="ts">
2
+ import { VisSingleContainer, VisDonut } from '@unovis/vue'
3
+ import type { TokenUsageSource } from '~~/shared/types'
4
+
5
+ interface SourceData {
6
+ source: TokenUsageSource
7
+ cost: number
8
+ calls: number
9
+ tokens: number
10
+ }
11
+
12
+ const props = defineProps<{
13
+ data: SourceData[]
14
+ title?: string
15
+ }>()
16
+
17
+ const sourceLabels: Record<TokenUsageSource, string> = {
18
+ chat: 'Chat',
19
+ agent: 'Agents',
20
+ memory_extraction: 'Memory'
21
+ }
22
+
23
+ const sourceColors: Record<TokenUsageSource, string> = {
24
+ chat: 'var(--ui-primary)',
25
+ agent: 'var(--ui-warning)',
26
+ memory_extraction: 'var(--ui-info)'
27
+ }
28
+
29
+ const value = (d: SourceData) => d.cost
30
+ const color = (d: SourceData) => sourceColors[d.source] || 'var(--ui-neutral)'
31
+
32
+ const totalCost = computed(() => props.data.reduce((sum, d) => sum + d.cost, 0))
33
+ </script>
34
+
35
+ <template>
36
+ <UCard>
37
+ <template
38
+ v-if="title"
39
+ #header
40
+ >
41
+ <p class="text-sm font-medium">
42
+ {{ title }}
43
+ </p>
44
+ </template>
45
+
46
+ <div
47
+ v-if="data.length === 0"
48
+ class="flex items-center justify-center h-64 text-muted"
49
+ >
50
+ No usage data
51
+ </div>
52
+
53
+ <div
54
+ v-else
55
+ class="flex items-center gap-6"
56
+ >
57
+ <VisSingleContainer
58
+ :data="data"
59
+ class="h-48 w-48 shrink-0"
60
+ >
61
+ <VisDonut
62
+ :value="value"
63
+ :color="color"
64
+ :arc-width="30"
65
+ :pad-angle="0.02"
66
+ :corner-radius="3"
67
+ />
68
+ </VisSingleContainer>
69
+
70
+ <div class="flex-1 space-y-3">
71
+ <div
72
+ v-for="item in data"
73
+ :key="item.source"
74
+ class="flex items-center justify-between"
75
+ >
76
+ <div class="flex items-center gap-2">
77
+ <span
78
+ class="inline-block size-3 rounded-full"
79
+ :style="{ background: sourceColors[item.source] }"
80
+ />
81
+ <span class="text-sm font-medium">{{ sourceLabels[item.source] }}</span>
82
+ </div>
83
+ <div class="text-right">
84
+ <span class="text-sm font-semibold">${{ item.cost.toFixed(2) }}</span>
85
+ <span class="text-xs text-muted ml-2">
86
+ {{ totalCost > 0 ? Math.round((item.cost / totalCost) * 100) : 0 }}%
87
+ </span>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </UCard>
93
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ defineProps<{
3
+ data?: unknown[]
4
+ title?: string
5
+ }>()
6
+ </script>
7
+
8
+ <template>
9
+ <UCard :ui="{ body: '!p-0' }">
10
+ <template
11
+ v-if="title"
12
+ #header
13
+ >
14
+ <p class="text-sm font-medium">
15
+ {{ title }}
16
+ </p>
17
+ </template>
18
+
19
+ <div class="h-64 bg-muted/5 rounded animate-pulse" />
20
+ </UCard>
21
+ </template>
@@ -0,0 +1,101 @@
1
+ <script setup lang="ts">
2
+ import type { UsageStats } from '~~/shared/types'
3
+
4
+ defineProps<{
5
+ stats: UsageStats | null
6
+ loading?: boolean
7
+ }>()
8
+
9
+ function formatCurrency(value: number): string {
10
+ if (value < 0.01 && value > 0) return '<$0.01'
11
+ return `$${value.toFixed(2)}`
12
+ }
13
+
14
+ function formatTokens(value: number): string {
15
+ if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`
16
+ if (value >= 1_000) return `${(value / 1_000).toFixed(1)}K`
17
+ return String(value)
18
+ }
19
+ </script>
20
+
21
+ <template>
22
+ <div class="grid gap-4 grid-cols-2 sm:grid-cols-3 lg:grid-cols-5">
23
+ <template v-if="loading">
24
+ <div
25
+ v-for="i in 5"
26
+ :key="i"
27
+ class="p-4 rounded-lg bg-elevated border border-default"
28
+ >
29
+ <USkeleton class="h-4 w-16 mb-2" />
30
+ <USkeleton class="h-8 w-12" />
31
+ </div>
32
+ </template>
33
+
34
+ <template v-else-if="stats">
35
+ <div class="p-4 rounded-lg bg-elevated border border-default">
36
+ <div class="flex items-center gap-2 text-muted text-sm mb-1">
37
+ <UIcon
38
+ name="i-lucide-dollar-sign"
39
+ class="size-4"
40
+ />
41
+ <span>Total Cost</span>
42
+ </div>
43
+ <p class="text-2xl font-semibold">
44
+ {{ formatCurrency(stats.totalCostUsd) }}
45
+ </p>
46
+ </div>
47
+
48
+ <div class="p-4 rounded-lg bg-elevated border border-default">
49
+ <div class="flex items-center gap-2 text-muted text-sm mb-1">
50
+ <UIcon
51
+ name="i-lucide-arrow-down"
52
+ class="size-4"
53
+ />
54
+ <span>Input Tokens</span>
55
+ </div>
56
+ <p class="text-2xl font-semibold">
57
+ {{ formatTokens(stats.totalInputTokens) }}
58
+ </p>
59
+ </div>
60
+
61
+ <div class="p-4 rounded-lg bg-elevated border border-default">
62
+ <div class="flex items-center gap-2 text-muted text-sm mb-1">
63
+ <UIcon
64
+ name="i-lucide-arrow-up"
65
+ class="size-4"
66
+ />
67
+ <span>Output Tokens</span>
68
+ </div>
69
+ <p class="text-2xl font-semibold">
70
+ {{ formatTokens(stats.totalOutputTokens) }}
71
+ </p>
72
+ </div>
73
+
74
+ <div class="p-4 rounded-lg bg-elevated border border-default">
75
+ <div class="flex items-center gap-2 text-muted text-sm mb-1">
76
+ <UIcon
77
+ name="i-lucide-zap"
78
+ class="size-4"
79
+ />
80
+ <span>API Calls</span>
81
+ </div>
82
+ <p class="text-2xl font-semibold">
83
+ {{ stats.totalCalls }}
84
+ </p>
85
+ </div>
86
+
87
+ <div class="p-4 rounded-lg bg-elevated border border-default">
88
+ <div class="flex items-center gap-2 text-muted text-sm mb-1">
89
+ <UIcon
90
+ name="i-lucide-calculator"
91
+ class="size-4"
92
+ />
93
+ <span>Avg / Call</span>
94
+ </div>
95
+ <p class="text-2xl font-semibold">
96
+ {{ formatCurrency(stats.avgCostPerCall) }}
97
+ </p>
98
+ </div>
99
+ </template>
100
+ </div>
101
+ </template>
@@ -0,0 +1,89 @@
1
+ <script setup lang="ts">
2
+ import type { TokenUsageSource } from '~~/shared/types'
3
+
4
+ interface Consumer {
5
+ name: string
6
+ source: TokenUsageSource
7
+ cost: number
8
+ calls: number
9
+ }
10
+
11
+ defineProps<{
12
+ data: Consumer[]
13
+ title?: string
14
+ }>()
15
+
16
+ const sourceLabels: Record<TokenUsageSource, string> = {
17
+ chat: 'Chat',
18
+ agent: 'Agent',
19
+ memory_extraction: 'Memory'
20
+ }
21
+
22
+ const sourceColors = {
23
+ chat: 'primary',
24
+ agent: 'warning',
25
+ memory_extraction: 'info'
26
+ } as const
27
+
28
+ function formatCurrency(value: number): string {
29
+ if (value < 0.01 && value > 0) return '<$0.01'
30
+ return `$${value.toFixed(4)}`
31
+ }
32
+ </script>
33
+
34
+ <template>
35
+ <UCard>
36
+ <template
37
+ v-if="title"
38
+ #header
39
+ >
40
+ <p class="text-sm font-medium">
41
+ {{ title }}
42
+ </p>
43
+ </template>
44
+
45
+ <div
46
+ v-if="data.length === 0"
47
+ class="flex items-center justify-center h-32 text-muted"
48
+ >
49
+ No usage data
50
+ </div>
51
+
52
+ <div
53
+ v-else
54
+ class="divide-y divide-default"
55
+ >
56
+ <div
57
+ v-for="(item, index) in data"
58
+ :key="`${item.source}-${item.name}`"
59
+ class="flex items-center justify-between py-2.5"
60
+ :class="{ 'pt-0': index === 0 }"
61
+ >
62
+ <div class="flex items-center gap-3 min-w-0">
63
+ <span class="text-sm text-muted w-5 text-right shrink-0">{{ index + 1 }}</span>
64
+ <div class="min-w-0">
65
+ <p class="text-sm font-medium truncate">
66
+ {{ item.name }}
67
+ </p>
68
+ <UBadge
69
+ :color="sourceColors[item.source]"
70
+ variant="subtle"
71
+ size="xs"
72
+ >
73
+ {{ sourceLabels[item.source] }}
74
+ </UBadge>
75
+ </div>
76
+ </div>
77
+
78
+ <div class="text-right shrink-0 ml-4">
79
+ <p class="text-sm font-semibold">
80
+ {{ formatCurrency(item.cost) }}
81
+ </p>
82
+ <p class="text-xs text-muted">
83
+ {{ item.calls }} {{ item.calls === 1 ? 'call' : 'calls' }}
84
+ </p>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </UCard>
89
+ </template>
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Copy text to clipboard with fallback for non-secure contexts (HTTP).
3
+ * navigator.clipboard.writeText() requires HTTPS or localhost.
4
+ * The fallback uses a hidden textarea + execCommand('copy').
5
+ */
6
+ export function useCopyToClipboard() {
7
+ async function copy(text: string): Promise<boolean> {
8
+ // Try modern clipboard API first (works on HTTPS / localhost)
9
+ if (navigator.clipboard?.writeText) {
10
+ try {
11
+ await navigator.clipboard.writeText(text)
12
+ return true
13
+ } catch {
14
+ // Fall through to legacy method
15
+ }
16
+ }
17
+
18
+ // Legacy fallback for HTTP / non-secure contexts
19
+ try {
20
+ const textarea = document.createElement('textarea')
21
+ textarea.value = text
22
+ textarea.style.position = 'fixed'
23
+ textarea.style.left = '-9999px'
24
+ textarea.style.top = '-9999px'
25
+ document.body.appendChild(textarea)
26
+ textarea.focus()
27
+ textarea.select()
28
+ const ok = document.execCommand('copy')
29
+ document.body.removeChild(textarea)
30
+ return ok
31
+ } catch {
32
+ return false
33
+ }
34
+ }
35
+
36
+ return { copy }
37
+ }
@@ -22,6 +22,9 @@ interface Preferences {
22
22
  // Agent stats
23
23
  agentStatsPeriod: '24h' | '7d' | '30d'
24
24
 
25
+ // Usage stats
26
+ usageStatsPeriod: '24h' | '7d' | '30d'
27
+
25
28
  // Onboarding
26
29
  onboardingDismissed: boolean
27
30
  }
@@ -41,6 +44,7 @@ const defaults: Preferences = {
41
44
  taskStatusFilter: 'all',
42
45
  taskProjectFilter: null,
43
46
  agentStatsPeriod: '7d',
47
+ usageStatsPeriod: '7d',
44
48
  onboardingDismissed: false
45
49
  }
46
50
 
@@ -114,6 +118,11 @@ export function usePreferences() {
114
118
  set: v => set('assistantLastConversationId', v)
115
119
  })
116
120
 
121
+ const usageStatsPeriod = computed({
122
+ get: () => get('usageStatsPeriod'),
123
+ set: v => set('usageStatsPeriod', v)
124
+ })
125
+
117
126
  const onboardingDismissed = computed({
118
127
  get: () => get('onboardingDismissed'),
119
128
  set: v => set('onboardingDismissed', v)
@@ -136,6 +145,7 @@ export function usePreferences() {
136
145
  taskStatusFilter,
137
146
  taskProjectFilter,
138
147
  agentStatsPeriod,
148
+ usageStatsPeriod,
139
149
  onboardingDismissed
140
150
  }
141
151
  }
@@ -56,6 +56,13 @@ const links = [[{
56
56
  onSelect: () => {
57
57
  open.value = false
58
58
  }
59
+ }, {
60
+ label: 'Usage',
61
+ icon: 'i-lucide-bar-chart-3',
62
+ to: '/usage',
63
+ onSelect: () => {
64
+ open.value = false
65
+ }
59
66
  }, {
60
67
  label: 'Chat',
61
68
  icon: 'i-lucide-message-square',
@@ -92,7 +99,7 @@ const links = [[{
92
99
  <span
93
100
  v-if="!collapsed"
94
101
  class="font-semibold text-lg"
95
- >Brain</span>
102
+ >Cognova</span>
96
103
  </div>
97
104
  </template>
98
105
 
@@ -29,8 +29,18 @@ onMounted(() => {
29
29
  connect()
30
30
  loadConversations()
31
31
 
32
+ // Load specific conversation from URL param (e.g., from dashboard)
33
+ if (route.query.conversation) {
34
+ const conversationId = route.query.conversation as string
35
+ const stop = watch(connectionStatus, (status) => {
36
+ if (status === 'connected') {
37
+ stop()
38
+ loadConversation(conversationId)
39
+ router.replace({ query: {} })
40
+ }
41
+ }, { immediate: true })
42
+ } else if (route.query.onboarding) {
32
43
  // Auto-send greeting when arriving from onboarding modal
33
- if (route.query.onboarding) {
34
44
  const stop = watch(connectionStatus, (status) => {
35
45
  if (status === 'connected') {
36
46
  stop()
@@ -1,80 +1,81 @@
1
1
  <script setup lang="ts">
2
+ import type { DashboardOverview } from '~~/shared/types'
3
+
2
4
  definePageMeta({
3
5
  layout: 'dashboard',
4
6
  middleware: 'auth'
5
7
  })
8
+
9
+ const { user } = useAuth()
10
+ const overview = ref<DashboardOverview | null>(null)
11
+ const loading = ref(true)
12
+
13
+ async function loadOverview() {
14
+ loading.value = true
15
+ try {
16
+ const res = await $fetch<{ data: DashboardOverview }>('/api/dashboard/overview')
17
+ overview.value = res.data
18
+ } catch {
19
+ // Silently fail — cards show empty state
20
+ } finally {
21
+ loading.value = false
22
+ }
23
+ }
24
+
25
+ onMounted(() => {
26
+ loadOverview()
27
+ })
6
28
  </script>
7
29
 
8
30
  <template>
9
- <UDashboardPanel
10
- id="dashboard"
11
- grow
12
- >
13
- <UDashboardNavbar title="Dashboard">
14
- <template #actions>
15
- <UColorModeButton />
31
+ <div class="contents">
32
+ <UDashboardPanel
33
+ id="dashboard"
34
+ grow
35
+ >
36
+ <template #header>
37
+ <UDashboardNavbar title="Dashboard" />
16
38
  </template>
17
- </UDashboardNavbar>
18
-
19
- <div class="p-6 overflow-auto">
20
- <div class="space-y-6">
21
- <div>
22
- <h1 class="text-2xl font-bold">
23
- Welcome to Cognova
24
- </h1>
25
- <p class="text-muted mt-1">
26
- Your personal knowledge management system.
27
- </p>
28
- </div>
29
39
 
30
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
31
- <UCard>
32
- <template #header>
33
- <div class="flex items-center gap-2">
34
- <UIcon
35
- name="i-lucide-check-square"
36
- class="size-5 text-primary"
37
- />
38
- <span class="font-semibold">Tasks Due Today</span>
39
- </div>
40
- </template>
41
- <p class="text-muted text-sm">
42
- No tasks due today.
40
+ <template #body>
41
+ <div class="p-4 space-y-6">
42
+ <div>
43
+ <h1 class="text-2xl font-bold">
44
+ Welcome back{{ user?.name ? `, ${user.name}` : '' }}
45
+ </h1>
46
+ <p class="text-muted mt-1 text-sm">
47
+ Here's what's happening in your workspace.
43
48
  </p>
44
- </UCard>
49
+ </div>
45
50
 
46
- <UCard>
47
- <template #header>
48
- <div class="flex items-center gap-2">
49
- <UIcon
50
- name="i-lucide-file-text"
51
- class="size-5 text-primary"
52
- />
53
- <span class="font-semibold">Recent Notes</span>
54
- </div>
55
- </template>
56
- <p class="text-muted text-sm">
57
- No recent notes.
58
- </p>
59
- </UCard>
51
+ <DashboardStatCards
52
+ :overview="overview"
53
+ :loading="loading"
54
+ />
55
+
56
+ <div class="grid gap-6 lg:grid-cols-2">
57
+ <DashboardUpcomingTasks
58
+ :tasks="overview?.tasks.upcoming ?? []"
59
+ :loading="loading"
60
+ />
61
+ <DashboardRecentChats
62
+ :conversations="overview?.conversations ?? []"
63
+ :loading="loading"
64
+ />
65
+ </div>
60
66
 
61
- <UCard>
62
- <template #header>
63
- <div class="flex items-center gap-2">
64
- <UIcon
65
- name="i-lucide-inbox"
66
- class="size-5 text-primary"
67
- />
68
- <span class="font-semibold">Quick Capture</span>
69
- </div>
70
- </template>
71
- <UInput
72
- placeholder="What's on your mind?"
73
- class="mt-2"
67
+ <div class="grid gap-6 lg:grid-cols-2">
68
+ <DashboardRecentDocs
69
+ :documents="overview?.documents ?? []"
70
+ :loading="loading"
71
+ />
72
+ <DashboardUsageSummary
73
+ :usage="overview?.usage ?? { totalCost7d: 0, totalCalls7d: 0, totalInputTokens7d: 0, totalOutputTokens7d: 0 }"
74
+ :loading="loading"
74
75
  />
75
- </UCard>
76
+ </div>
76
77
  </div>
77
- </div>
78
- </div>
79
- </UDashboardPanel>
78
+ </template>
79
+ </UDashboardPanel>
80
+ </div>
80
81
  </template>