cognova 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/-AsXrBBy.js +1 -0
- package/.output/public/_nuxt/2W1RPpXM.js +71 -0
- package/.output/public/_nuxt/{C4pxqdgg.js → 5UFq_rDn.js} +1 -1
- package/.output/public/_nuxt/5Zh-9l8_.js +1 -0
- package/.output/public/_nuxt/{DK9jxJ0g.js → 90UksHlj.js} +1 -1
- package/.output/public/_nuxt/{9IQmsEjr.js → 9QKmiSP_.js} +1 -1
- package/.output/public/_nuxt/{BOj6t-oo.js → ARbTpeGy.js} +1 -1
- package/.output/public/_nuxt/{DyRelyfs.js → ApfLnl06.js} +1 -1
- package/.output/public/_nuxt/{DznawRFW.js → B-2BuR5g.js} +1 -1
- package/.output/public/_nuxt/B4u7Mczo.js +1 -0
- package/.output/public/_nuxt/{DAQhmSv4.js → B5dI_yLq.js} +1 -1
- package/.output/public/_nuxt/{Bm9LyG4F.js → B6fnZcA6.js} +1 -1
- package/.output/public/_nuxt/{9QnH0xQM.js → B7uMSBlN.js} +1 -1
- package/.output/public/_nuxt/BBiRyPlN.js +1 -0
- package/.output/public/_nuxt/{iBGCpHdw.js → BF7413u4.js} +2 -2
- package/.output/public/_nuxt/{4MiwzAAt.js → BGtUoCgi.js} +2 -2
- package/.output/public/_nuxt/{CxuZBC8n.js → BHe4VLtR.js} +1 -1
- package/.output/public/_nuxt/{D3RiUGdz.js → BIMBp1Tj.js} +1 -1
- package/.output/public/_nuxt/{g20UHUCv.js → BIvPdoE3.js} +1 -1
- package/.output/public/_nuxt/BKaRtCjP.js +1 -0
- package/.output/public/_nuxt/BLmc9T7l.js +1 -0
- package/.output/public/_nuxt/BMdnU6BF.js +1 -0
- package/.output/public/_nuxt/{CKkC3Ptm.js → BOgdaA_8.js} +1 -1
- package/.output/public/_nuxt/{BffWCM73.js → BQZfTrUg.js} +1 -1
- package/.output/public/_nuxt/BQnublTW.js +1 -0
- package/.output/public/_nuxt/BSsvedap.js +1 -0
- package/.output/public/_nuxt/{Ci7UEZQh.js → BVypxKRT.js} +1 -1
- package/.output/public/_nuxt/{CYP_MLH8.js → BWqJFnZy.js} +1 -1
- package/.output/public/_nuxt/BXxYdXMr.js +1 -0
- package/.output/public/_nuxt/{D_3Rq1BS.js → B_17gAr_.js} +1 -1
- package/.output/public/_nuxt/B_qzFVK_.js +1 -0
- package/.output/public/_nuxt/{BqKFIuRj.js → BbRPwpIX.js} +1 -1
- package/.output/public/_nuxt/BhrzKbv9.js +1 -0
- package/.output/public/_nuxt/{Cqy_L_ip.js → Bl6LNGlA.js} +1 -1
- package/.output/public/_nuxt/{Fukkqjkf.js → BlPToGni.js} +1 -1
- package/.output/public/_nuxt/{DHKLCQRG.js → BlwHr46F.js} +1 -1
- package/.output/public/_nuxt/{C6aqGHu1.js → BnmwiZbF.js} +1 -1
- package/.output/public/_nuxt/BqtxLJaf.js +1 -0
- package/.output/public/_nuxt/{eko-0FUm.js → BrEXdify.js} +1 -1
- package/.output/public/_nuxt/{D3e44mCL.js → BtNnS4m3.js} +1 -1
- package/.output/public/_nuxt/{BCtfQCzC.js → BtVIBBUN.js} +1 -1
- package/.output/public/_nuxt/Bw5h4Jaf.js +1 -0
- package/.output/public/_nuxt/{FvlxxmNk.js → Bwcpy7gC.js} +2 -2
- package/.output/public/_nuxt/{Db2v8O7O.js → C0TUK31m.js} +1 -1
- package/.output/public/_nuxt/C1T4GK6c.js +1 -0
- package/.output/public/_nuxt/C2ANDZen.js +1 -0
- package/.output/public/_nuxt/{CqU2XbzO.js → C2RZSTuy.js} +1 -1
- package/.output/public/_nuxt/C3dYlP5x.js +1 -0
- package/.output/public/_nuxt/{m5kGCDpI.js → C3sh_tLi.js} +3 -3
- package/.output/public/_nuxt/{BjjCvHLT.js → C4zyxZG7.js} +1 -1
- package/.output/public/_nuxt/{C3FxIITy.js → C5I-XBZT.js} +1 -1
- package/.output/public/_nuxt/{yuf23kh9.js → CC4Goztu.js} +1 -1
- package/.output/public/_nuxt/CC77iplr.js +1 -0
- package/.output/public/_nuxt/{xuzLdW-o.js → CFyD2NHP.js} +1 -1
- package/.output/public/_nuxt/{CsJ9KhQ4.js → CGQDTeaO.js} +1 -1
- package/.output/public/_nuxt/{DnjGH3SQ.js → CHpwuMSk.js} +1 -1
- package/.output/public/_nuxt/CLzcRUcs.js +1 -0
- package/.output/public/_nuxt/CM2phu_3.js +1 -0
- package/.output/public/_nuxt/{Cr8ixbr1.js → CQpYRq61.js} +1 -1
- package/.output/public/_nuxt/{C0JKNMDO.js → CUN4bYcg.js} +1 -1
- package/.output/public/_nuxt/{CmzH6R-N.js → CXoITXft.js} +19 -19
- package/.output/public/_nuxt/CYjcQPl-.js +1 -0
- package/.output/public/_nuxt/{DGX0tzL8.js → CZ32KfaS.js} +1 -1
- package/.output/public/_nuxt/CclZMdca.js +1 -0
- package/.output/public/_nuxt/{C69W7k2j.js → CdpT_Vb6.js} +1 -1
- package/.output/public/_nuxt/CflRLvFC.js +1 -0
- package/.output/public/_nuxt/{gBC9k4Qj.js → CkqNv7sq.js} +2 -2
- package/.output/public/_nuxt/ClXDAYjE.js +1 -0
- package/.output/public/_nuxt/CrZGoMo_.js +1 -0
- package/.output/public/_nuxt/{BZXMQuYP.js → CvJtd2Af.js} +1 -1
- package/.output/public/_nuxt/{DKZxeXDQ.js → Cwtd8e-P.js} +1 -1
- package/.output/public/_nuxt/{nIU2F7ia.js → Cx44SSNp.js} +3 -3
- package/.output/public/_nuxt/{BzOqrmGa.js → CxEVzuCn.js} +3 -3
- package/.output/public/_nuxt/{Dy_Cq5LQ.js → CzIMQevQ.js} +1 -1
- package/.output/public/_nuxt/{D6t3dcTl.js → D0P9llU7.js} +1 -1
- package/.output/public/_nuxt/{JJ3634gV.js → D1DYuOOm.js} +1 -1
- package/.output/public/_nuxt/{BAIz-dEB.js → D1dDc8Vw.js} +1 -1
- package/.output/public/_nuxt/{DSRrg8JT.js → D1r0uqf3.js} +1 -1
- package/.output/public/_nuxt/{CNnJrDvu.js → D3a8R1T6.js} +1 -1
- package/.output/public/_nuxt/{B1X4Bzcy.js → D5EZbuub.js} +1 -1
- package/.output/public/_nuxt/D9V13KTK.js +1 -0
- package/.output/public/_nuxt/DAE2hbP7.js +1 -0
- package/.output/public/_nuxt/{Cvp7FI3T.js → DAIbdyS6.js} +1 -1
- package/.output/public/_nuxt/{EuOqK1A6.js → DAvlXjt0.js} +1 -1
- package/.output/public/_nuxt/DBKzwexZ.js +1 -0
- package/.output/public/_nuxt/{wCGVE8_e.js → DEATxnaF.js} +1 -1
- package/.output/public/_nuxt/{cABRLVee.js → DFg8PvHV.js} +1 -1
- package/.output/public/_nuxt/DM4MyqI-.js +1 -0
- package/.output/public/_nuxt/{Cdt3I3Go.js → DNE7kw9s.js} +1 -1
- package/.output/public/_nuxt/DO0oG4fG.js +1 -0
- package/.output/public/_nuxt/{B6S_ob86.js → DPFugPaB.js} +1 -1
- package/.output/public/_nuxt/{DJjDvbZE.js → DQlXU6_H.js} +1 -1
- package/.output/public/_nuxt/DQvuQpwh.js +1 -0
- package/.output/public/_nuxt/{sf57orEk.js → DRlG_bnX.js} +1 -1
- package/.output/public/_nuxt/{C6RC3lA1.js → DSQj-oMk.js} +1 -1
- package/.output/public/_nuxt/{CeIVm4A3.js → DU6ewLkE.js} +1 -1
- package/.output/public/_nuxt/{Cp2MA0cm.js → DWhzQg7B.js} +1 -1
- package/.output/public/_nuxt/{DJMS2og1.js → D_vK6VPK.js} +1 -1
- package/.output/public/_nuxt/{CihWZmJe.js → DaBp0Gba.js} +2 -2
- package/.output/public/_nuxt/DaH2FbAy.js +1 -0
- package/.output/public/_nuxt/{CtYFj7k1.js → DaJo0CeV.js} +1 -1
- package/.output/public/_nuxt/DauLdT7p.js +1 -0
- package/.output/public/_nuxt/{DG-T44jj.js → DdPA4eTX.js} +1 -1
- package/.output/public/_nuxt/{YuTZB7sD.js → DeAGWdWK.js} +1 -1
- package/.output/public/_nuxt/{CitkKxhw.js → DfF1qofg.js} +1 -1
- package/.output/public/_nuxt/{Daz4MeL6.js → DiGBA-aA.js} +1 -1
- package/.output/public/_nuxt/DiJxF69i.js +1 -0
- package/.output/public/_nuxt/{DIoI0uJm.js → DkBIU-1F.js} +1 -1
- package/.output/public/_nuxt/DmAM6bZ0.js +1 -0
- package/.output/public/_nuxt/DmeAKr3J.js +1 -0
- package/.output/public/_nuxt/DmmTnMzZ.js +1 -0
- package/.output/public/_nuxt/{Lwdv_RKd.js → DqsUSndS.js} +1 -1
- package/.output/public/_nuxt/Dvw-hR3Y.js +1 -0
- package/.output/public/_nuxt/{CVgTJeSq.js → Dz6sfh81.js} +1 -1
- package/.output/public/_nuxt/{BYjadNrw.js → FNhYm5FX.js} +1 -1
- package/.output/public/_nuxt/{Nb2jBtYT.js → HOeKUnra.js} +1 -1
- package/.output/public/_nuxt/{CtchsY6e.js → IR1jkN7B.js} +1 -1
- package/.output/public/_nuxt/{DCzfkCGa.js → MpTk6K7N.js} +1 -1
- package/.output/public/_nuxt/NZ7Wz6LP.js +1 -0
- package/.output/public/_nuxt/{DfQu3kEw.js → PqWbiAD2.js} +1 -1
- package/.output/public/_nuxt/{Jez9DHn7.js → Tu4FhMRc.js} +1 -1
- package/.output/public/_nuxt/{B3y_Qqox.js → UKPXYG4z.js} +1 -1
- package/.output/public/_nuxt/{BlAZO7nq.js → UO2Y9Nve.js} +1 -1
- package/.output/public/_nuxt/{KKK6HVeG.js → XHiJSquP.js} +1 -1
- package/.output/public/_nuxt/YGWAImQo.js +1 -0
- package/.output/public/_nuxt/{ghuJ76mD.js → ZR87XvwB.js} +1 -1
- package/.output/public/_nuxt/{yNrp2XvX.js → _E89BQAO.js} +1 -1
- package/.output/public/_nuxt/{C_BdYLzz.js → aiXk7zRt.js} +1 -1
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/91727fcc-bf7f-407f-9b1e-092017fcfee0.json +1 -0
- package/.output/public/_nuxt/cL7whuPe.js +1 -0
- package/.output/public/_nuxt/{BasgsT_S.js → ct6_k5IW.js} +1 -1
- package/.output/public/_nuxt/entry._7ZkP07A.css +1 -0
- package/.output/public/_nuxt/{DTDgHTuh.js → fEUQvmn8.js} +2 -2
- package/.output/public/_nuxt/{FNC8XZTk.js → gGlaVUMD.js} +1 -1
- package/.output/public/_nuxt/gjmGkVlL.js +1 -0
- package/.output/public/_nuxt/{IRSbVPIu.js → m5001Uvl.js} +1 -1
- package/.output/public/_nuxt/{_CYZi8HN.js → mQkFCz_M.js} +1 -1
- package/.output/public/_nuxt/{BxXOsXrM.js → p9l1LjVc.js} +10 -10
- package/.output/public/_nuxt/{BsEZoHd1.js → qR_K5W8V.js} +1 -1
- package/.output/public/_nuxt/{BrNqhp1a.js → t_9QQ4MF.js} +7 -7
- package/.output/public/_nuxt/{pcUI-zuY.js → uc4c4mfb.js} +1 -1
- package/.output/public/_nuxt/{usage.vakN1lvi.css → usage.BDeyCZwW.css} +1 -1
- package/.output/public/_nuxt/wPSLEMBw.js +1 -0
- package/.output/public/_nuxt/xKRwul0f.js +1 -0
- package/.output/public/_nuxt/{BWhMnjID.js → xgpiGSxb.js} +1 -1
- package/.output/public/_nuxt/xxnk7j0F.js +1 -0
- package/.output/public/favicon.svg +1 -0
- package/.output/server/chunks/build/A-BWukSPjS.mjs +1 -0
- package/.output/server/chunks/build/Accordion-BaJYea6e.mjs +1 -0
- package/.output/server/chunks/build/AccordionItem-DdG2zgcN.mjs +1 -0
- package/.output/server/chunks/build/Badge-BrU9UkCv.mjs +1 -0
- package/.output/server/chunks/build/Blockquote-DND8wTkU.mjs +1 -0
- package/.output/server/chunks/build/Callout-1halpaEg.mjs +1 -0
- package/.output/server/chunks/build/Card-BHCSDKDt.mjs +1 -0
- package/.output/server/chunks/build/CardGroup-BOuJcNGp.mjs +1 -0
- package/.output/server/chunks/build/Caution-BP3y-TcC.mjs +1 -0
- package/.output/server/chunks/build/Code-B1xkAS5a.mjs +1 -0
- package/.output/server/chunks/build/CodeCollapse-BIhaNa22.mjs +1 -0
- package/.output/server/chunks/build/CodeGroup-BviYyCuo.mjs +1 -0
- package/.output/server/chunks/build/CodeIcon-CWD5HcV7.mjs +2 -1
- package/.output/server/chunks/build/CodePreview-D8PsCQ6m.mjs +1 -0
- package/.output/server/chunks/build/CodeTree-BUTLupmL.mjs +1 -0
- package/.output/server/chunks/build/Collapsible-BIvXNaSq.mjs +1 -0
- package/.output/server/chunks/build/DropdownMenu-BBrV9nXz.mjs +1 -1
- package/.output/server/chunks/build/EditorToolbar-DIfb5arC.mjs +1 -1
- package/.output/server/chunks/build/Em-DsIz_BnD.mjs +1 -0
- package/.output/server/chunks/build/Field-cwwmSQDT.mjs +1 -0
- package/.output/server/chunks/build/FieldGroup-CAIpQv8s.mjs +1 -0
- package/.output/server/chunks/build/H1-BbFNsPyP.mjs +1 -0
- package/.output/server/chunks/build/H2-vHTl_pWr.mjs +1 -0
- package/.output/server/chunks/build/H3-7eTcfO3s.mjs +1 -0
- package/.output/server/chunks/build/H4-C89p_PKO.mjs +1 -0
- package/.output/server/chunks/build/Hr-Bm8RlL3O.mjs +1 -0
- package/.output/server/chunks/build/Icon-Dp9iy0BI.mjs +1 -0
- package/.output/server/chunks/build/Img-CWLmvN1t.mjs +2 -1
- package/.output/server/chunks/build/Kbd-CQG6I_Ch.mjs +1 -0
- package/.output/server/chunks/build/Li-Bw1QUaGv.mjs +1 -0
- package/.output/server/chunks/build/MDC-Dx0YPDhe.mjs +1 -1
- package/.output/server/chunks/build/Note-CHkjm9jm.mjs +1 -0
- package/.output/server/chunks/build/Ol-D-fPnfFM.mjs +1 -0
- package/.output/server/chunks/build/P-B5YI1V9y.mjs +1 -0
- package/.output/server/chunks/build/Pre-ChiJcf3C.mjs +1 -0
- package/.output/server/chunks/build/ProseH5-DahJyv8h.mjs +1 -0
- package/.output/server/chunks/build/ProseH6-C4Is5h6c.mjs +1 -0
- package/.output/server/chunks/build/Select-BB1oLrCD.mjs +1 -1
- package/.output/server/chunks/build/SelectMenu-DPssg6zD.mjs +1 -1
- package/.output/server/chunks/build/Steps-BZpvXfzb.mjs +1 -0
- package/.output/server/chunks/build/Strong-DXJqOWL3.mjs +1 -0
- package/.output/server/chunks/build/Table-BSrLZ7dt.mjs +1 -0
- package/.output/server/chunks/build/Table-DCwTlhCj.mjs +1 -1
- package/.output/server/chunks/build/Tabs-Dk3nvOFF.mjs +1 -0
- package/.output/server/chunks/build/TabsItem-CDhyuBtJ.mjs +1 -0
- package/.output/server/chunks/build/Tbody-CjMT5oH-.mjs +1 -0
- package/.output/server/chunks/build/Td-ZBVaEjFN.mjs +1 -0
- package/.output/server/chunks/build/Th-D317icbd.mjs +1 -0
- package/.output/server/chunks/build/Thead-Ca_ZESTK.mjs +1 -0
- package/.output/server/chunks/build/Tip-CP3oTARR.mjs +1 -0
- package/.output/server/chunks/build/Tooltip-TRyl6dje.mjs +1 -1
- package/.output/server/chunks/build/Tr-6jI8j9gD.mjs +1 -0
- package/.output/server/chunks/build/{docs-Dk2JnYq3.mjs → Tree-DUhXKd8y.mjs} +46 -2235
- package/.output/server/chunks/build/Tree-DUhXKd8y.mjs.map +1 -0
- package/.output/server/chunks/build/Ul-BUGj_CPb.mjs +1 -0
- package/.output/server/chunks/build/Warning-BJ8G6cxC.mjs +1 -0
- package/.output/server/chunks/build/_id_-DN00UDdO.mjs +1 -0
- package/.output/server/chunks/build/_id_-DN00UDdO.mjs.map +1 -1
- package/.output/server/chunks/build/_name_-BnS_KEfX.mjs +1592 -0
- package/.output/server/chunks/build/_name_-BnS_KEfX.mjs.map +1 -0
- package/.output/server/chunks/build/{_uuid_-0UgdUhfY.mjs → _uuid_-DfJaumTE.mjs} +5 -4
- package/.output/server/chunks/build/{_uuid_-0UgdUhfY.mjs.map → _uuid_-DfJaumTE.mjs.map} +1 -1
- package/.output/server/chunks/build/auth-BGPNH2QJ.mjs +20 -0
- package/.output/server/chunks/build/auth-BGPNH2QJ.mjs.map +1 -0
- package/.output/server/chunks/build/auth-CvD7MqKW.mjs +1 -0
- package/.output/server/chunks/build/auth-CvD7MqKW.mjs.map +1 -1
- package/.output/server/chunks/build/chat-CZMiB68R.mjs +1 -0
- package/.output/server/chunks/build/chat-CZMiB68R.mjs.map +1 -1
- package/.output/server/chunks/build/client.precomputed.mjs +1 -1
- package/.output/server/chunks/build/cookie-C_iulBi6.mjs +1 -1
- package/.output/server/chunks/build/{dashboard-YEscLBQN.mjs → dashboard-CLk1NlbR.mjs} +15 -4
- package/.output/server/chunks/build/dashboard-CLk1NlbR.mjs.map +1 -0
- package/.output/server/chunks/build/{dashboard-CpMVYnDV.mjs → dashboard-CiVTAZuF.mjs} +12 -4
- package/.output/server/chunks/build/{dashboard-CpMVYnDV.mjs.map → dashboard-CiVTAZuF.mjs.map} +1 -1
- package/.output/server/chunks/build/docs-ChGwOPg5.mjs +2204 -0
- package/.output/server/chunks/build/docs-ChGwOPg5.mjs.map +1 -0
- package/.output/server/chunks/build/error-404-BzbcNcdU.mjs +1 -0
- package/.output/server/chunks/build/error-500-uCDjGRW8.mjs +1 -0
- package/.output/server/chunks/build/fetch-BB7Qzkwe.mjs +1 -1
- package/.output/server/chunks/build/{hooks-DP8WoUPS.mjs → hooks-D328DcO6.mjs} +3 -2
- package/.output/server/chunks/build/hooks-D328DcO6.mjs.map +1 -0
- package/.output/server/chunks/build/{index-DVx-QlhP.mjs → index-Byt-3Yq6.mjs} +3 -2
- package/.output/server/chunks/build/{index-DVx-QlhP.mjs.map → index-Byt-3Yq6.mjs.map} +1 -1
- package/.output/server/chunks/build/{index-Ba_bPJgk.mjs → index-C9PuieXh.mjs} +3 -2
- package/.output/server/chunks/build/index-C9PuieXh.mjs.map +1 -0
- package/.output/server/chunks/build/index-C_LcBBgO.mjs +1508 -0
- package/.output/server/chunks/build/index-C_LcBBgO.mjs.map +1 -0
- package/.output/server/chunks/build/index-CxDxc9fm.mjs +1 -1
- package/.output/server/chunks/build/index-DzdvIi8V.mjs +1 -0
- package/.output/server/chunks/build/library-CbWcF5wT.mjs +601 -0
- package/.output/server/chunks/build/library-CbWcF5wT.mjs.map +1 -0
- package/.output/server/chunks/build/{login-BAysbpyX.mjs → login-DnnElTl2.mjs} +15 -7
- package/.output/server/chunks/build/{login-BAysbpyX.mjs.map → login-DnnElTl2.mjs.map} +1 -1
- package/.output/server/chunks/build/memories-BqA719O1.mjs +1 -0
- package/.output/server/chunks/build/memories-BqA719O1.mjs.map +1 -1
- package/.output/server/chunks/build/server.mjs +62 -34
- package/.output/server/chunks/build/server.mjs.map +1 -1
- package/.output/server/chunks/build/settings-DdkKCJ00.mjs +1 -0
- package/.output/server/chunks/build/settings-DdkKCJ00.mjs.map +1 -1
- package/.output/server/chunks/build/styles.mjs +2 -2
- package/.output/server/chunks/build/{tasks-DiOi1HG_.mjs → tasks-DnAFqbtt.mjs} +3 -2
- package/.output/server/chunks/build/tasks-DnAFqbtt.mjs.map +1 -0
- package/.output/server/chunks/build/{usage-H_mcd_fz.mjs → usage-CSrBh4Or.mjs} +159 -44
- package/.output/server/chunks/build/{usage-H_mcd_fz.mjs.map → usage-CSrBh4Or.mjs.map} +1 -1
- package/.output/server/chunks/build/{usePreferences-CzC8fRzd.mjs → usePreferences-DH1QjxOj.mjs} +7 -1
- package/.output/server/chunks/build/usePreferences-DH1QjxOj.mjs.map +1 -0
- package/.output/server/chunks/build/{view-Dc8mvzCB.mjs → view-n2sYa4Zh.mjs} +4 -3
- package/.output/server/chunks/build/{view-Dc8mvzCB.mjs.map → view-n2sYa4Zh.mjs.map} +1 -1
- package/.output/server/chunks/build/virtual_nuxt__Users_tony_Documents_GitHub_second-brain_node_modules_.cache_nuxt_.nuxt_mdc-imports-PtwWlZ2H.mjs +1 -0
- package/.output/server/chunks/nitro/nitro.mjs +1247 -824
- package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
- package/.output/server/chunks/routes/_ws/chat.mjs +2 -1
- package/.output/server/chunks/routes/_ws/chat.mjs.map +1 -1
- package/.output/server/chunks/routes/api/agents/_id/cancel.post.mjs +1 -0
- package/.output/server/chunks/routes/api/agents/_id/cancel.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/agents/_id/run.post.mjs +1 -0
- package/.output/server/chunks/routes/api/agents/_id/run.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/agents/_id/runs.get.mjs +1 -0
- package/.output/server/chunks/routes/api/agents/_id/runs.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/agents/_id/stats.get.mjs +1 -0
- package/.output/server/chunks/routes/api/agents/_id/stats.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/agents/_id_.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/agents/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/agents/_id_.get.mjs +1 -0
- package/.output/server/chunks/routes/api/agents/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/agents/_id_.patch.mjs +1 -0
- package/.output/server/chunks/routes/api/agents/_id_.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/api/agents/stats.get.mjs +1 -0
- package/.output/server/chunks/routes/api/agents/stats.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/auth/_...all_.mjs +1 -0
- package/.output/server/chunks/routes/api/auth/_...all_.mjs.map +1 -1
- package/.output/server/chunks/routes/api/conversations/_id_.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/conversations/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/conversations/_id_.get.mjs +1 -0
- package/.output/server/chunks/routes/api/conversations/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/dashboard/overview.get.mjs +1 -0
- package/.output/server/chunks/routes/api/dashboard/overview.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/documents/_id/public.get.mjs +1 -0
- package/.output/server/chunks/routes/api/documents/_id/public.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/documents/_id/restore.post.mjs +1 -0
- package/.output/server/chunks/routes/api/documents/_id/restore.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/documents/by-path.post.mjs +1 -0
- package/.output/server/chunks/routes/api/documents/by-path.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/documents/index.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/documents/index.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/documents/index.put.mjs +1 -0
- package/.output/server/chunks/routes/api/documents/index.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/fs/delete.post.mjs +1 -0
- package/.output/server/chunks/routes/api/fs/delete.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/fs/list.get.mjs +1 -0
- package/.output/server/chunks/routes/api/fs/list.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/fs/mkdir.post.mjs +1 -0
- package/.output/server/chunks/routes/api/fs/mkdir.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/fs/move.post.mjs +1 -0
- package/.output/server/chunks/routes/api/fs/move.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/fs/read.post.mjs +1 -0
- package/.output/server/chunks/routes/api/fs/read.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/fs/rename.post.mjs +1 -0
- package/.output/server/chunks/routes/api/fs/rename.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/fs/write.post.mjs +1 -0
- package/.output/server/chunks/routes/api/fs/write.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/health.get.mjs +1 -0
- package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/home.get.mjs +1 -0
- package/.output/server/chunks/routes/api/home.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/hooks/index.get.mjs +1 -0
- package/.output/server/chunks/routes/api/hooks/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/hooks/index.post.mjs +1 -0
- package/.output/server/chunks/routes/api/hooks/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/hooks/stats.get.mjs +1 -0
- package/.output/server/chunks/routes/api/hooks/stats.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get.mjs +1 -0
- package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get2.mjs +1 -0
- package/.output/server/chunks/routes/api/index.get2.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get3.mjs +1 -0
- package/.output/server/chunks/routes/api/index.get3.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get4.mjs +1 -0
- package/.output/server/chunks/routes/api/index.get4.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get5.mjs +1 -0
- package/.output/server/chunks/routes/api/index.get5.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get6.mjs +1 -0
- package/.output/server/chunks/routes/api/index.get6.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get7.mjs +40 -38
- package/.output/server/chunks/routes/api/index.get7.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get8.mjs +33 -38
- package/.output/server/chunks/routes/api/index.get8.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get9.mjs +83 -0
- package/.output/server/chunks/routes/api/index.get9.mjs.map +1 -0
- package/.output/server/chunks/routes/api/index.post.mjs +1 -0
- package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.post2.mjs +1 -0
- package/.output/server/chunks/routes/api/index.post2.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.post3.mjs +1 -0
- package/.output/server/chunks/routes/api/index.post3.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.post4.mjs +1 -0
- package/.output/server/chunks/routes/api/index.post4.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.put.mjs +1 -0
- package/.output/server/chunks/routes/api/index.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/memory/_id_.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/memory/_id_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/memory/context.get.mjs +1 -0
- package/.output/server/chunks/routes/api/memory/context.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/memory/extract.post.mjs +2 -1
- package/.output/server/chunks/routes/api/memory/extract.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/memory/search.get.mjs +1 -0
- package/.output/server/chunks/routes/api/memory/search.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/memory/store.post.mjs +1 -0
- package/.output/server/chunks/routes/api/memory/store.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/projects/index.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/projects/index.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/projects/index.get.mjs +1 -0
- package/.output/server/chunks/routes/api/projects/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/projects/index.put.mjs +1 -0
- package/.output/server/chunks/routes/api/projects/index.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/secrets/_key_.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/secrets/_key_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/secrets/_key_.get.mjs +1 -0
- package/.output/server/chunks/routes/api/secrets/_key_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/secrets/_key_.put.mjs +1 -0
- package/.output/server/chunks/routes/api/secrets/_key_.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/skills/_name/export.get.mjs +72 -0
- package/.output/server/chunks/routes/api/skills/_name/export.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/_name/files/create.post.mjs +73 -0
- package/.output/server/chunks/routes/api/skills/_name/files/create.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/_name/files/delete.post.mjs +71 -0
- package/.output/server/chunks/routes/api/skills/_name/files/delete.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/_name/files/read.post.mjs +69 -0
- package/.output/server/chunks/routes/api/skills/_name/files/read.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/_name/files/write.post.mjs +69 -0
- package/.output/server/chunks/routes/api/skills/_name/files/write.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/_name/index.get.mjs +60 -0
- package/.output/server/chunks/routes/api/skills/_name/index.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/_name/rename.post.mjs +87 -0
- package/.output/server/chunks/routes/api/skills/_name/rename.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/_name/toggle.post.mjs +62 -0
- package/.output/server/chunks/routes/api/skills/_name/toggle.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/create.post.mjs +79 -0
- package/.output/server/chunks/routes/api/skills/create.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/generate.post.mjs +143 -0
- package/.output/server/chunks/routes/api/skills/generate.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/import.post.mjs +96 -0
- package/.output/server/chunks/routes/api/skills/import.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/index.get.mjs +82 -0
- package/.output/server/chunks/routes/api/skills/index.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/index.get2.mjs +83 -0
- package/.output/server/chunks/routes/api/skills/index.get2.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/library/check-updates.get.mjs +72 -0
- package/.output/server/chunks/routes/api/skills/library/check-updates.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/skills/library/install.post.mjs +90 -0
- package/.output/server/chunks/routes/api/skills/library/install.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/tasks/_id/restore.post.mjs +1 -0
- package/.output/server/chunks/routes/api/tasks/_id/restore.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/tasks/index.delete.mjs +1 -0
- package/.output/server/chunks/routes/api/tasks/index.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/tasks/index.get.mjs +1 -0
- package/.output/server/chunks/routes/api/tasks/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/tasks/index.put.mjs +1 -0
- package/.output/server/chunks/routes/api/tasks/index.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/tasks/tags.get.mjs +1 -0
- package/.output/server/chunks/routes/api/tasks/tags.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/usage/stats.get.mjs +4 -1
- package/.output/server/chunks/routes/api/usage/stats.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/user/email.patch.mjs +2 -1
- package/.output/server/chunks/routes/api/user/email.patch.mjs.map +1 -1
- package/.output/server/chunks/routes/notifications.mjs +2 -1
- package/.output/server/chunks/routes/notifications.mjs.map +1 -1
- package/.output/server/chunks/routes/renderer.mjs +2 -2
- package/.output/server/chunks/routes/terminal.mjs +2 -1
- package/.output/server/chunks/routes/terminal.mjs.map +1 -1
- package/.output/server/index.mjs +2 -1
- package/.output/server/index.mjs.map +1 -1
- package/.output/server/node_modules/adm-zip/adm-zip.js +949 -0
- package/.output/server/node_modules/adm-zip/headers/entryHeader.js +374 -0
- package/.output/server/node_modules/adm-zip/headers/index.js +2 -0
- package/.output/server/node_modules/adm-zip/headers/mainHeader.js +130 -0
- package/.output/server/node_modules/adm-zip/methods/deflater.js +33 -0
- package/.output/server/node_modules/adm-zip/methods/index.js +3 -0
- package/.output/server/node_modules/adm-zip/methods/inflater.js +34 -0
- package/.output/server/node_modules/adm-zip/methods/zipcrypto.js +175 -0
- package/.output/server/node_modules/adm-zip/package.json +49 -0
- package/.output/server/node_modules/adm-zip/util/constants.js +142 -0
- package/.output/server/node_modules/adm-zip/util/decoder.js +5 -0
- package/.output/server/node_modules/adm-zip/util/errors.js +63 -0
- package/.output/server/node_modules/adm-zip/util/fattr.js +76 -0
- package/.output/server/node_modules/adm-zip/util/index.js +5 -0
- package/.output/server/node_modules/adm-zip/util/utils.js +336 -0
- package/.output/server/node_modules/adm-zip/zipEntry.js +405 -0
- package/.output/server/node_modules/adm-zip/zipFile.js +446 -0
- package/.output/server/package.json +2 -1
- package/README.md +3 -0
- package/app/app.vue +1 -1
- package/app/components/dashboard/StatCards.vue +21 -2
- package/app/components/usage/UsageCostChart.client.vue +59 -23
- package/app/components/usage/UsageCostChart.server.vue +1 -0
- package/app/components/usage/UsageSourceDonut.client.vue +17 -5
- package/app/components/usage/UsageSourceDonut.server.vue +1 -0
- package/app/components/usage/UsageTopConsumers.vue +13 -3
- package/app/composables/usePreferences.ts +9 -1
- package/app/layouts/auth.vue +0 -10
- package/app/pages/login.vue +18 -8
- package/app/pages/skills/[name].vue +12 -0
- package/app/pages/skills/index.vue +47 -0
- package/app/pages/usage.vue +43 -16
- package/dist/cli/index.js +12 -13
- package/package.json +5 -3
- package/server/api/skills/[name]/export.get.ts +45 -0
- package/server/api/skills/import.post.ts +87 -0
- package/server/api/usage/stats.get.ts +4 -2
- package/shared/types/index.ts +2 -1
- package/.output/public/_nuxt/5ZXA0Ckq.js +0 -1
- package/.output/public/_nuxt/BIIJhjQO.js +0 -1
- package/.output/public/_nuxt/BIckl6wA.js +0 -1
- package/.output/public/_nuxt/BJ3o57WW.js +0 -1
- package/.output/public/_nuxt/BNetzZzF.js +0 -1
- package/.output/public/_nuxt/BS0ofHJK.js +0 -1
- package/.output/public/_nuxt/B_3_hrpn.js +0 -1
- package/.output/public/_nuxt/BaBZjmMC.js +0 -1
- package/.output/public/_nuxt/BaMqDm5u.js +0 -1
- package/.output/public/_nuxt/BhzMoffi.js +0 -1
- package/.output/public/_nuxt/BlhFigLL.js +0 -1
- package/.output/public/_nuxt/BoIxv-gM.js +0 -1
- package/.output/public/_nuxt/Br19oYkq.js +0 -1
- package/.output/public/_nuxt/C0kh_F7v.js +0 -1
- package/.output/public/_nuxt/C61KgSco.js +0 -1
- package/.output/public/_nuxt/CJUdYEdO.js +0 -1
- package/.output/public/_nuxt/CVJQGP1Q.js +0 -1
- package/.output/public/_nuxt/CWMUi89H.js +0 -1
- package/.output/public/_nuxt/Cdu2qGgq.js +0 -1
- package/.output/public/_nuxt/CeIu7z4p.js +0 -1
- package/.output/public/_nuxt/D2689qk4.js +0 -1
- package/.output/public/_nuxt/D31L7Ks6.js +0 -1
- package/.output/public/_nuxt/DB359q8R.js +0 -1
- package/.output/public/_nuxt/DHG66LPS.js +0 -1
- package/.output/public/_nuxt/DJ5V-y_x.js +0 -1
- package/.output/public/_nuxt/DLETdGFL.js +0 -1
- package/.output/public/_nuxt/DOICd-Ld.js +0 -1
- package/.output/public/_nuxt/DPEcH-gi.js +0 -65
- package/.output/public/_nuxt/Db8-_gO7.js +0 -1
- package/.output/public/_nuxt/DgV-EDJ9.js +0 -1
- package/.output/public/_nuxt/Dp2X5R2m.js +0 -1
- package/.output/public/_nuxt/DqB723Z0.js +0 -1
- package/.output/public/_nuxt/Q8Ps7oN5.js +0 -1
- package/.output/public/_nuxt/SXTDhzp6.js +0 -1
- package/.output/public/_nuxt/Sg2Lwc46.js +0 -1
- package/.output/public/_nuxt/_J_7XIn-.js +0 -1
- package/.output/public/_nuxt/builds/meta/a1e9100c-1a4f-4f7e-bb53-9dbe0d07effb.json +0 -1
- package/.output/public/_nuxt/entry.CGxIBGAf.css +0 -1
- package/.output/public/_nuxt/inmzPrjz.js +0 -1
- package/.output/public/_nuxt/oIX-ZDN6.js +0 -1
- package/.output/server/chunks/build/auth-CDHRohj4.mjs +0 -77
- package/.output/server/chunks/build/auth-CDHRohj4.mjs.map +0 -1
- package/.output/server/chunks/build/dashboard-YEscLBQN.mjs.map +0 -1
- package/.output/server/chunks/build/docs-Dk2JnYq3.mjs.map +0 -1
- package/.output/server/chunks/build/hooks-DP8WoUPS.mjs.map +0 -1
- package/.output/server/chunks/build/index-Ba_bPJgk.mjs.map +0 -1
- package/.output/server/chunks/build/tasks-DiOi1HG_.mjs.map +0 -1
- package/.output/server/chunks/build/usePreferences-CzC8fRzd.mjs.map +0 -1
- /package/.output/public/_nuxt/{useCopyToClipboard.Be_IvFWy.css → CodeEditor.Be_IvFWy.css} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { VisSingleContainer, VisDonut } from '@unovis/vue'
|
|
3
|
-
import type { TokenUsageSource } from '~~/shared/types'
|
|
3
|
+
import type { TokenUsageSource, UsageDisplayMode } from '~~/shared/types'
|
|
4
4
|
|
|
5
5
|
interface SourceData {
|
|
6
6
|
source: TokenUsageSource
|
|
@@ -12,6 +12,7 @@ interface SourceData {
|
|
|
12
12
|
const props = defineProps<{
|
|
13
13
|
data: SourceData[]
|
|
14
14
|
title?: string
|
|
15
|
+
displayMode?: UsageDisplayMode
|
|
15
16
|
}>()
|
|
16
17
|
|
|
17
18
|
const sourceLabels: Record<TokenUsageSource, string> = {
|
|
@@ -26,10 +27,19 @@ const sourceColors: Record<TokenUsageSource, string> = {
|
|
|
26
27
|
memory_extraction: 'var(--ui-info)'
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
const
|
|
30
|
+
const isTokens = computed(() => props.displayMode === 'tokens')
|
|
31
|
+
const value = (d: SourceData) => isTokens.value ? d.tokens : d.cost
|
|
30
32
|
const color = (d: SourceData) => sourceColors[d.source] || 'var(--ui-neutral)'
|
|
31
33
|
|
|
32
|
-
const
|
|
34
|
+
const total = computed(() =>
|
|
35
|
+
props.data.reduce((sum, d) => sum + (isTokens.value ? d.tokens : d.cost), 0)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
function formatTokens(v: number): string {
|
|
39
|
+
if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`
|
|
40
|
+
if (v >= 1_000) return `${(v / 1_000).toFixed(1)}K`
|
|
41
|
+
return String(v)
|
|
42
|
+
}
|
|
33
43
|
</script>
|
|
34
44
|
|
|
35
45
|
<template>
|
|
@@ -81,9 +91,11 @@ const totalCost = computed(() => props.data.reduce((sum, d) => sum + d.cost, 0))
|
|
|
81
91
|
<span class="text-sm font-medium">{{ sourceLabels[item.source] }}</span>
|
|
82
92
|
</div>
|
|
83
93
|
<div class="text-right">
|
|
84
|
-
<span class="text-sm font-semibold"
|
|
94
|
+
<span class="text-sm font-semibold">
|
|
95
|
+
{{ isTokens ? formatTokens(item.tokens) : `$${item.cost.toFixed(2)}` }}
|
|
96
|
+
</span>
|
|
85
97
|
<span class="text-xs text-muted ml-2">
|
|
86
|
-
{{
|
|
98
|
+
{{ total > 0 ? Math.round(((isTokens ? item.tokens : item.cost) / total) * 100) : 0 }}%
|
|
87
99
|
</span>
|
|
88
100
|
</div>
|
|
89
101
|
</div>
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type { TokenUsageSource } from '~~/shared/types'
|
|
2
|
+
import type { TokenUsageSource, UsageDisplayMode } from '~~/shared/types'
|
|
3
3
|
|
|
4
4
|
interface Consumer {
|
|
5
5
|
name: string
|
|
6
6
|
source: TokenUsageSource
|
|
7
7
|
cost: number
|
|
8
8
|
calls: number
|
|
9
|
+
tokens: number
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
defineProps<{
|
|
12
|
+
const props = defineProps<{
|
|
12
13
|
data: Consumer[]
|
|
13
14
|
title?: string
|
|
15
|
+
displayMode?: UsageDisplayMode
|
|
14
16
|
}>()
|
|
15
17
|
|
|
16
18
|
const sourceLabels: Record<TokenUsageSource, string> = {
|
|
@@ -25,10 +27,18 @@ const sourceColors = {
|
|
|
25
27
|
memory_extraction: 'info'
|
|
26
28
|
} as const
|
|
27
29
|
|
|
30
|
+
const isTokens = computed(() => props.displayMode === 'tokens')
|
|
31
|
+
|
|
28
32
|
function formatCurrency(value: number): string {
|
|
29
33
|
if (value < 0.01 && value > 0) return '<$0.01'
|
|
30
34
|
return `$${value.toFixed(4)}`
|
|
31
35
|
}
|
|
36
|
+
|
|
37
|
+
function formatTokens(value: number): string {
|
|
38
|
+
if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`
|
|
39
|
+
if (value >= 1_000) return `${(value / 1_000).toFixed(1)}K`
|
|
40
|
+
return String(value)
|
|
41
|
+
}
|
|
32
42
|
</script>
|
|
33
43
|
|
|
34
44
|
<template>
|
|
@@ -77,7 +87,7 @@ function formatCurrency(value: number): string {
|
|
|
77
87
|
|
|
78
88
|
<div class="text-right shrink-0 ml-4">
|
|
79
89
|
<p class="text-sm font-semibold">
|
|
80
|
-
{{ formatCurrency(item.cost) }}
|
|
90
|
+
{{ isTokens ? formatTokens(item.tokens) : formatCurrency(item.cost) }}
|
|
81
91
|
</p>
|
|
82
92
|
<p class="text-xs text-muted">
|
|
83
93
|
{{ item.calls }} {{ item.calls === 1 ? 'call' : 'calls' }}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TaskStatus } from '~~/shared/types'
|
|
1
|
+
import type { TaskStatus, UsageDisplayMode } from '~~/shared/types'
|
|
2
2
|
|
|
3
3
|
interface Preferences {
|
|
4
4
|
// Editor preferences
|
|
@@ -24,6 +24,7 @@ interface Preferences {
|
|
|
24
24
|
|
|
25
25
|
// Usage stats
|
|
26
26
|
usageStatsPeriod: '24h' | '7d' | '30d'
|
|
27
|
+
usageDisplayMode: UsageDisplayMode
|
|
27
28
|
|
|
28
29
|
// Onboarding
|
|
29
30
|
onboardingDismissed: boolean
|
|
@@ -45,6 +46,7 @@ const defaults: Preferences = {
|
|
|
45
46
|
taskProjectFilter: null,
|
|
46
47
|
agentStatsPeriod: '7d',
|
|
47
48
|
usageStatsPeriod: '7d',
|
|
49
|
+
usageDisplayMode: 'tokens',
|
|
48
50
|
onboardingDismissed: false
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -123,6 +125,11 @@ export function usePreferences() {
|
|
|
123
125
|
set: v => set('usageStatsPeriod', v)
|
|
124
126
|
})
|
|
125
127
|
|
|
128
|
+
const usageDisplayMode = computed({
|
|
129
|
+
get: () => get('usageDisplayMode'),
|
|
130
|
+
set: v => set('usageDisplayMode', v)
|
|
131
|
+
})
|
|
132
|
+
|
|
126
133
|
const onboardingDismissed = computed({
|
|
127
134
|
get: () => get('onboardingDismissed'),
|
|
128
135
|
set: v => set('onboardingDismissed', v)
|
|
@@ -146,6 +153,7 @@ export function usePreferences() {
|
|
|
146
153
|
taskProjectFilter,
|
|
147
154
|
agentStatsPeriod,
|
|
148
155
|
usageStatsPeriod,
|
|
156
|
+
usageDisplayMode,
|
|
149
157
|
onboardingDismissed
|
|
150
158
|
}
|
|
151
159
|
}
|
package/app/layouts/auth.vue
CHANGED
|
@@ -4,16 +4,6 @@
|
|
|
4
4
|
<template>
|
|
5
5
|
<div class="min-h-screen flex items-center justify-center bg-default">
|
|
6
6
|
<div class="w-full max-w-md px-4">
|
|
7
|
-
<div class="flex flex-col items-center gap-6 mb-8">
|
|
8
|
-
<div class="flex items-center gap-3">
|
|
9
|
-
<UIcon
|
|
10
|
-
name="i-lucide-brain"
|
|
11
|
-
class="size-10 text-primary"
|
|
12
|
-
/>
|
|
13
|
-
<span class="font-bold text-2xl">Cognova</span>
|
|
14
|
-
</div>
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
7
|
<slot />
|
|
18
8
|
</div>
|
|
19
9
|
</div>
|
package/app/pages/login.vue
CHANGED
|
@@ -49,12 +49,22 @@ async function handleSubmit(event: { data: { email: string, password: string } }
|
|
|
49
49
|
</script>
|
|
50
50
|
|
|
51
51
|
<template>
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
<div>
|
|
53
|
+
<div class="flex flex-col items-center gap-6 mb-8">
|
|
54
|
+
<div class="flex items-center gap-3">
|
|
55
|
+
<UIcon
|
|
56
|
+
name="i-lucide-brain"
|
|
57
|
+
class="size-10 text-primary"
|
|
58
|
+
/>
|
|
59
|
+
<span class="font-bold text-2xl">Cognova</span>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
<UAuthForm
|
|
63
|
+
title="Sign In"
|
|
64
|
+
description="Enter your credentials to access your account"
|
|
65
|
+
:fields="fields"
|
|
66
|
+
:submit="{ label: 'Sign In', loading }"
|
|
67
|
+
@submit="handleSubmit"
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
60
70
|
</template>
|
|
@@ -55,6 +55,10 @@ function handleRenamed(newName: string) {
|
|
|
55
55
|
router.replace(`/skills/${newName}`)
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
function handleExport() {
|
|
59
|
+
window.open(`/api/skills/${skillName.value}/export`, '_blank')
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
onMounted(() => loadSkill())
|
|
59
63
|
</script>
|
|
60
64
|
|
|
@@ -151,6 +155,14 @@ onMounted(() => loadSkill())
|
|
|
151
155
|
size="sm"
|
|
152
156
|
@click="renameOpen = true"
|
|
153
157
|
/>
|
|
158
|
+
<UButton
|
|
159
|
+
v-if="skill"
|
|
160
|
+
icon="i-lucide-download"
|
|
161
|
+
variant="ghost"
|
|
162
|
+
color="neutral"
|
|
163
|
+
size="sm"
|
|
164
|
+
@click="handleExport"
|
|
165
|
+
/>
|
|
154
166
|
</template>
|
|
155
167
|
</UDashboardNavbar>
|
|
156
168
|
</template>
|
|
@@ -11,6 +11,8 @@ const skills = ref<SkillListItem[]>([])
|
|
|
11
11
|
const loading = ref(true)
|
|
12
12
|
const search = ref('')
|
|
13
13
|
const createOpen = ref(false)
|
|
14
|
+
const importing = ref(false)
|
|
15
|
+
const fileInput = ref<HTMLInputElement | null>(null)
|
|
14
16
|
|
|
15
17
|
const filteredSkills = computed(() => {
|
|
16
18
|
if (!search.value.trim()) return skills.value
|
|
@@ -33,6 +35,34 @@ async function loadSkills() {
|
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
async function handleImport(event: Event) {
|
|
39
|
+
const input = event.target as HTMLInputElement
|
|
40
|
+
const file = input.files?.[0]
|
|
41
|
+
if (!file) return
|
|
42
|
+
|
|
43
|
+
importing.value = true
|
|
44
|
+
try {
|
|
45
|
+
const formData = new FormData()
|
|
46
|
+
formData.append('file', file)
|
|
47
|
+
const res = await $fetch<{ data: { name: string, fileCount: number } }>('/api/skills/import', {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
body: formData
|
|
50
|
+
})
|
|
51
|
+
toast.add({
|
|
52
|
+
title: `Imported ${res.data.name}`,
|
|
53
|
+
description: `${res.data.fileCount} file${res.data.fileCount === 1 ? '' : 's'}`,
|
|
54
|
+
color: 'success'
|
|
55
|
+
})
|
|
56
|
+
navigateTo(`/skills/${res.data.name}`)
|
|
57
|
+
} catch (err: unknown) {
|
|
58
|
+
const message = err instanceof Error ? err.message : 'Import failed'
|
|
59
|
+
toast.add({ title: 'Import failed', description: message, color: 'error' })
|
|
60
|
+
} finally {
|
|
61
|
+
importing.value = false
|
|
62
|
+
input.value = ''
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
36
66
|
async function handleToggle(name: string) {
|
|
37
67
|
try {
|
|
38
68
|
const res = await $fetch<{ data: { name: string, active: boolean } }>(`/api/skills/${name}/toggle`, {
|
|
@@ -78,6 +108,23 @@ onMounted(() => loadSkills())
|
|
|
78
108
|
Library
|
|
79
109
|
</UButton>
|
|
80
110
|
</NuxtLink>
|
|
111
|
+
<UButton
|
|
112
|
+
icon="i-lucide-upload"
|
|
113
|
+
variant="ghost"
|
|
114
|
+
color="neutral"
|
|
115
|
+
size="sm"
|
|
116
|
+
:loading="importing"
|
|
117
|
+
@click="fileInput?.click()"
|
|
118
|
+
>
|
|
119
|
+
Import
|
|
120
|
+
</UButton>
|
|
121
|
+
<input
|
|
122
|
+
ref="fileInput"
|
|
123
|
+
type="file"
|
|
124
|
+
accept=".zip"
|
|
125
|
+
class="hidden"
|
|
126
|
+
@change="handleImport"
|
|
127
|
+
>
|
|
81
128
|
<UButton
|
|
82
129
|
icon="i-lucide-plus"
|
|
83
130
|
size="sm"
|
package/app/pages/usage.vue
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type { StatsPeriod, UsageStats } from '~~/shared/types'
|
|
2
|
+
import type { StatsPeriod, UsageStats, UsageDisplayMode } from '~~/shared/types'
|
|
3
3
|
|
|
4
4
|
definePageMeta({
|
|
5
5
|
layout: 'dashboard',
|
|
6
6
|
middleware: 'auth'
|
|
7
7
|
})
|
|
8
8
|
|
|
9
|
-
const { usageStatsPeriod } = usePreferences()
|
|
9
|
+
const { usageStatsPeriod, usageDisplayMode } = usePreferences()
|
|
10
10
|
const period = ref<StatsPeriod>(usageStatsPeriod.value)
|
|
11
|
+
const displayMode = ref<UsageDisplayMode>(usageDisplayMode.value)
|
|
11
12
|
const granularity = ref<'daily' | 'hourly'>('daily')
|
|
12
13
|
const stats = ref<UsageStats | null>(null)
|
|
13
14
|
const loading = ref(false)
|
|
@@ -18,6 +19,11 @@ const periodOptions = [
|
|
|
18
19
|
{ label: '30d', value: '30d' as StatsPeriod }
|
|
19
20
|
]
|
|
20
21
|
|
|
22
|
+
const displayModeOptions = [
|
|
23
|
+
{ label: 'Tokens', value: 'tokens' as UsageDisplayMode },
|
|
24
|
+
{ label: 'Cost', value: 'cost' as UsageDisplayMode }
|
|
25
|
+
]
|
|
26
|
+
|
|
21
27
|
async function loadStats() {
|
|
22
28
|
loading.value = true
|
|
23
29
|
try {
|
|
@@ -41,6 +47,10 @@ watch(period, (value) => {
|
|
|
41
47
|
loadStats()
|
|
42
48
|
})
|
|
43
49
|
|
|
50
|
+
watch(displayMode, (value) => {
|
|
51
|
+
usageDisplayMode.value = value
|
|
52
|
+
})
|
|
53
|
+
|
|
44
54
|
watch(granularity, () => {
|
|
45
55
|
loadStats()
|
|
46
56
|
})
|
|
@@ -59,18 +69,32 @@ onMounted(() => {
|
|
|
59
69
|
<template #header>
|
|
60
70
|
<UDashboardNavbar title="Token Usage">
|
|
61
71
|
<template #right>
|
|
62
|
-
<
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
<div class="flex items-center gap-4">
|
|
73
|
+
<UFieldGroup>
|
|
74
|
+
<UButton
|
|
75
|
+
v-for="opt in displayModeOptions"
|
|
76
|
+
:key="opt.value"
|
|
77
|
+
:color="displayMode === opt.value ? 'primary' : 'neutral'"
|
|
78
|
+
:variant="displayMode === opt.value ? 'solid' : 'ghost'"
|
|
79
|
+
size="sm"
|
|
80
|
+
@click="displayMode = opt.value"
|
|
81
|
+
>
|
|
82
|
+
{{ opt.label }}
|
|
83
|
+
</UButton>
|
|
84
|
+
</UFieldGroup>
|
|
85
|
+
<UFieldGroup>
|
|
86
|
+
<UButton
|
|
87
|
+
v-for="opt in periodOptions"
|
|
88
|
+
:key="opt.value"
|
|
89
|
+
:color="period === opt.value ? 'primary' : 'neutral'"
|
|
90
|
+
:variant="period === opt.value ? 'solid' : 'ghost'"
|
|
91
|
+
size="sm"
|
|
92
|
+
@click="period = opt.value"
|
|
93
|
+
>
|
|
94
|
+
{{ opt.label }}
|
|
95
|
+
</UButton>
|
|
96
|
+
</UFieldGroup>
|
|
97
|
+
</div>
|
|
74
98
|
</template>
|
|
75
99
|
</UDashboardNavbar>
|
|
76
100
|
</template>
|
|
@@ -86,19 +110,22 @@ onMounted(() => {
|
|
|
86
110
|
v-if="stats && stats.dailyUsage.length > 0"
|
|
87
111
|
v-model:granularity="granularity"
|
|
88
112
|
:data="stats.dailyUsage"
|
|
89
|
-
|
|
113
|
+
:display-mode="displayMode"
|
|
114
|
+
:title="displayMode === 'tokens' ? 'Tokens Over Time' : 'Cost Over Time'"
|
|
90
115
|
/>
|
|
91
116
|
|
|
92
117
|
<div class="grid gap-6 lg:grid-cols-2">
|
|
93
118
|
<UsageSourceDonut
|
|
94
119
|
v-if="stats && stats.bySource.length > 0"
|
|
95
120
|
:data="stats.bySource"
|
|
96
|
-
|
|
121
|
+
:display-mode="displayMode"
|
|
122
|
+
:title="displayMode === 'tokens' ? 'Tokens by Source' : 'Cost by Source'"
|
|
97
123
|
/>
|
|
98
124
|
|
|
99
125
|
<UsageTopConsumers
|
|
100
126
|
v-if="stats && stats.topConsumers.length > 0"
|
|
101
127
|
:data="stats.topConsumers"
|
|
128
|
+
:display-mode="displayMode"
|
|
102
129
|
title="Top Consumers"
|
|
103
130
|
/>
|
|
104
131
|
</div>
|
package/dist/cli/index.js
CHANGED
|
@@ -2339,25 +2339,24 @@ async function update() {
|
|
|
2339
2339
|
}
|
|
2340
2340
|
if (latestVersion === metadata.version) {
|
|
2341
2341
|
s.stop(`Already on latest version (${metadata.version})`);
|
|
2342
|
-
|
|
2343
|
-
|
|
2342
|
+
Le("Nothing to update.");
|
|
2343
|
+
return;
|
|
2344
2344
|
}
|
|
2345
|
+
s.stop(`Update available: ${metadata.version} \u2192 ${import_picocolors6.default.green(latestVersion)}`);
|
|
2345
2346
|
s.start("Creating backup");
|
|
2346
2347
|
const backupDir = createBackup(installDir);
|
|
2347
2348
|
s.stop("Backup created");
|
|
2348
2349
|
let updateFailed = false;
|
|
2349
2350
|
try {
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
rmSync(tmpDir, { recursive: true, force: true });
|
|
2360
|
-
}
|
|
2351
|
+
s.start("Downloading latest version");
|
|
2352
|
+
const tmpDir = execSync7("mktemp -d", { encoding: "utf-8" }).trim();
|
|
2353
|
+
try {
|
|
2354
|
+
execSync7(`npm pack cognova@${latestVersion} --pack-destination ${tmpDir}`, { stdio: "pipe" });
|
|
2355
|
+
execSync7(`tar -xzf ${tmpDir}/cognova-${latestVersion}.tgz -C ${tmpDir}`, { stdio: "pipe" });
|
|
2356
|
+
copyAppSource(`${tmpDir}/package`, installDir);
|
|
2357
|
+
s.stop("Source files updated");
|
|
2358
|
+
} finally {
|
|
2359
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
2361
2360
|
}
|
|
2362
2361
|
s.start("Syncing Claude config");
|
|
2363
2362
|
syncClaudeConfig(installDir);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognova",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.3",
|
|
5
5
|
"description": "Personal knowledge management system with Claude Code integration",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -75,12 +75,14 @@
|
|
|
75
75
|
"@xterm/addon-fit": "^0.11.0",
|
|
76
76
|
"@xterm/addon-web-links": "^0.12.0",
|
|
77
77
|
"@xterm/xterm": "^6.0.0",
|
|
78
|
+
"adm-zip": "^0.5.16",
|
|
78
79
|
"better-auth": "^1.4.17",
|
|
79
80
|
"chokidar": "^5.0.0",
|
|
80
81
|
"codemirror": "^6.0.2",
|
|
81
82
|
"cron": "^4.4.0",
|
|
82
83
|
"date-fns": "^4.1.0",
|
|
83
84
|
"dotenv": "^17.2.3",
|
|
85
|
+
"drizzle-kit": "^0.31.8",
|
|
84
86
|
"drizzle-orm": "^0.45.1",
|
|
85
87
|
"gray-matter": "^4.0.3",
|
|
86
88
|
"node-pty": "^1.1.0",
|
|
@@ -88,11 +90,11 @@
|
|
|
88
90
|
"postgres": "^3.4.8",
|
|
89
91
|
"shiki": "^3.21.0",
|
|
90
92
|
"sortablejs": "^1.15.6",
|
|
91
|
-
"tailwindcss": "^4.0.0"
|
|
92
|
-
"drizzle-kit": "^0.31.8"
|
|
93
|
+
"tailwindcss": "^4.0.0"
|
|
93
94
|
},
|
|
94
95
|
"devDependencies": {
|
|
95
96
|
"@nuxt/eslint": "^1.12.1",
|
|
97
|
+
"@types/adm-zip": "^0.5.7",
|
|
96
98
|
"@types/node": "^25.0.8",
|
|
97
99
|
"@types/sortablejs": "^1.15.9",
|
|
98
100
|
"eslint": "^9.39.2",
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { stat } from 'fs/promises'
|
|
2
|
+
import { join } from 'path'
|
|
3
|
+
import AdmZip from 'adm-zip'
|
|
4
|
+
import { getSkillsDir, getInactiveSkillsDir, validateSkillName } from '~~/server/utils/skills-path'
|
|
5
|
+
|
|
6
|
+
export default defineEventHandler(async (event) => {
|
|
7
|
+
const name = getRouterParam(event, 'name')
|
|
8
|
+
if (!name)
|
|
9
|
+
throw createError({ statusCode: 400, message: 'Skill name required' })
|
|
10
|
+
|
|
11
|
+
const nameError = validateSkillName(name)
|
|
12
|
+
if (nameError)
|
|
13
|
+
throw createError({ statusCode: 400, message: nameError })
|
|
14
|
+
|
|
15
|
+
// Check active first, then inactive
|
|
16
|
+
const activeDir = join(getSkillsDir(), name)
|
|
17
|
+
const inactiveDir = join(getInactiveSkillsDir(), name)
|
|
18
|
+
|
|
19
|
+
let skillDir = ''
|
|
20
|
+
|
|
21
|
+
const activeStat = await stat(activeDir).catch(() => null)
|
|
22
|
+
if (activeStat?.isDirectory()) {
|
|
23
|
+
skillDir = activeDir
|
|
24
|
+
} else {
|
|
25
|
+
const inactiveStat = await stat(inactiveDir).catch(() => null)
|
|
26
|
+
if (inactiveStat?.isDirectory())
|
|
27
|
+
skillDir = inactiveDir
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!skillDir)
|
|
31
|
+
throw createError({ statusCode: 404, message: `Skill '${name}' not found` })
|
|
32
|
+
|
|
33
|
+
const zip = new AdmZip()
|
|
34
|
+
zip.addLocalFolder(skillDir, name, /^(?!.*(__pycache__|\.pyc))/)
|
|
35
|
+
|
|
36
|
+
const buffer = zip.toBuffer()
|
|
37
|
+
|
|
38
|
+
setResponseHeaders(event, {
|
|
39
|
+
'Content-Type': 'application/zip',
|
|
40
|
+
'Content-Disposition': `attachment; filename="${name}.zip"`,
|
|
41
|
+
'Content-Length': String(buffer.length)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
return send(event, buffer)
|
|
45
|
+
})
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { stat, mkdir, writeFile } from 'fs/promises'
|
|
2
|
+
import { join, normalize } from 'path'
|
|
3
|
+
import AdmZip from 'adm-zip'
|
|
4
|
+
import { getSkillsDir, getInactiveSkillsDir, validateSkillName } from '~~/server/utils/skills-path'
|
|
5
|
+
|
|
6
|
+
export default defineEventHandler(async (event) => {
|
|
7
|
+
const form = await readMultipartFormData(event)
|
|
8
|
+
if (!form)
|
|
9
|
+
throw createError({ statusCode: 400, message: 'Multipart form data required' })
|
|
10
|
+
|
|
11
|
+
const fileField = form.find(f => f.name === 'file')
|
|
12
|
+
if (!fileField?.data)
|
|
13
|
+
throw createError({ statusCode: 400, message: 'No file uploaded' })
|
|
14
|
+
|
|
15
|
+
const zip = new AdmZip(Buffer.from(fileField.data))
|
|
16
|
+
const entries = zip.getEntries()
|
|
17
|
+
|
|
18
|
+
if (entries.length === 0)
|
|
19
|
+
throw createError({ statusCode: 400, message: 'Zip file is empty' })
|
|
20
|
+
|
|
21
|
+
// Determine skill name from root folder or filename
|
|
22
|
+
const firstEntry = entries[0].entryName
|
|
23
|
+
const rootFolder = firstEntry.includes('/') ? firstEntry.split('/')[0] : null
|
|
24
|
+
const fileName = fileField.filename?.replace(/\.zip$/i, '') || ''
|
|
25
|
+
const skillName = rootFolder || fileName
|
|
26
|
+
|
|
27
|
+
if (!skillName)
|
|
28
|
+
throw createError({ statusCode: 400, message: 'Could not determine skill name from zip' })
|
|
29
|
+
|
|
30
|
+
const nameError = validateSkillName(skillName)
|
|
31
|
+
if (nameError)
|
|
32
|
+
throw createError({ statusCode: 400, message: `Invalid skill name: ${nameError}` })
|
|
33
|
+
|
|
34
|
+
// Check skill doesn't already exist
|
|
35
|
+
const activeDir = join(getSkillsDir(), skillName)
|
|
36
|
+
const inactiveDir = join(getInactiveSkillsDir(), skillName)
|
|
37
|
+
|
|
38
|
+
const activeExists = await stat(activeDir).catch(() => null)
|
|
39
|
+
const inactiveExists = await stat(inactiveDir).catch(() => null)
|
|
40
|
+
|
|
41
|
+
if (activeExists || inactiveExists)
|
|
42
|
+
throw createError({ statusCode: 409, message: `Skill '${skillName}' already exists` })
|
|
43
|
+
|
|
44
|
+
// Validate zip contains SKILL.md
|
|
45
|
+
const hasSkillMd = entries.some((e) => {
|
|
46
|
+
const parts = e.entryName.split('/')
|
|
47
|
+
// SKILL.md at root or inside one-level folder
|
|
48
|
+
return parts[parts.length - 1] === 'SKILL.md'
|
|
49
|
+
|| (parts.length === 2 && parts[1] === 'SKILL.md')
|
|
50
|
+
})
|
|
51
|
+
if (!hasSkillMd)
|
|
52
|
+
throw createError({ statusCode: 400, message: 'Zip must contain a SKILL.md file' })
|
|
53
|
+
|
|
54
|
+
// Extract to skills dir with path traversal protection
|
|
55
|
+
const targetDir = activeDir
|
|
56
|
+
await mkdir(targetDir, { recursive: true })
|
|
57
|
+
|
|
58
|
+
let fileCount = 0
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
if (entry.isDirectory) continue
|
|
61
|
+
|
|
62
|
+
// Strip root folder prefix if present
|
|
63
|
+
let relativePath = entry.entryName
|
|
64
|
+
if (rootFolder && relativePath.startsWith(rootFolder + '/'))
|
|
65
|
+
relativePath = relativePath.slice(rootFolder.length + 1)
|
|
66
|
+
|
|
67
|
+
if (!relativePath) continue
|
|
68
|
+
|
|
69
|
+
// Skip __pycache__ and .pyc files
|
|
70
|
+
if (relativePath.includes('__pycache__') || relativePath.endsWith('.pyc'))
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
// Path traversal check
|
|
74
|
+
const fullPath = normalize(join(targetDir, relativePath))
|
|
75
|
+
if (!fullPath.startsWith(targetDir))
|
|
76
|
+
throw createError({ statusCode: 400, message: 'Path traversal detected in zip entry' })
|
|
77
|
+
|
|
78
|
+
// Ensure parent directory exists
|
|
79
|
+
const parentDir = join(fullPath, '..')
|
|
80
|
+
await mkdir(parentDir, { recursive: true })
|
|
81
|
+
|
|
82
|
+
await writeFile(fullPath, entry.getData())
|
|
83
|
+
fileCount++
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return { data: { name: skillName, fileCount } }
|
|
87
|
+
})
|
|
@@ -57,7 +57,7 @@ export default defineEventHandler(async (event) => {
|
|
|
57
57
|
const sourceMap = new Map<TokenUsageSource, { cost: number, calls: number, tokens: number }>()
|
|
58
58
|
|
|
59
59
|
// Top consumers
|
|
60
|
-
const consumerMap = new Map<string, { name: string, source: TokenUsageSource, cost: number, calls: number }>()
|
|
60
|
+
const consumerMap = new Map<string, { name: string, source: TokenUsageSource, cost: number, calls: number, tokens: number }>()
|
|
61
61
|
|
|
62
62
|
for (const r of records) {
|
|
63
63
|
totalCostUsd += r.costUsd
|
|
@@ -99,10 +99,12 @@ export default defineEventHandler(async (event) => {
|
|
|
99
99
|
name: r.sourceName || 'Unknown',
|
|
100
100
|
source,
|
|
101
101
|
cost: 0,
|
|
102
|
-
calls: 0
|
|
102
|
+
calls: 0,
|
|
103
|
+
tokens: 0
|
|
103
104
|
}
|
|
104
105
|
consumer.cost += r.costUsd
|
|
105
106
|
consumer.calls++
|
|
107
|
+
consumer.tokens += r.inputTokens + r.outputTokens
|
|
106
108
|
consumerMap.set(consumerKey, consumer)
|
|
107
109
|
}
|
|
108
110
|
|
package/shared/types/index.ts
CHANGED
|
@@ -345,6 +345,7 @@ export interface UserSettings {
|
|
|
345
345
|
// === Agent Stats ===
|
|
346
346
|
|
|
347
347
|
export type StatsPeriod = '24h' | '7d' | '30d'
|
|
348
|
+
export type UsageDisplayMode = 'cost' | 'tokens'
|
|
348
349
|
|
|
349
350
|
export interface DailyRunData {
|
|
350
351
|
date: string
|
|
@@ -412,7 +413,7 @@ export interface UsageStats {
|
|
|
412
413
|
avgCostPerCall: number
|
|
413
414
|
dailyUsage: DailyUsageData[]
|
|
414
415
|
bySource: { source: TokenUsageSource, cost: number, calls: number, tokens: number }[]
|
|
415
|
-
topConsumers: { name: string, source: TokenUsageSource, cost: number, calls: number }[]
|
|
416
|
+
topConsumers: { name: string, source: TokenUsageSource, cost: number, calls: number, tokens: number }[]
|
|
416
417
|
}
|
|
417
418
|
|
|
418
419
|
// === Dashboard ===
|