cognova 0.2.0 → 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.
Files changed (548) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/-AsXrBBy.js +1 -0
  3. package/.output/public/_nuxt/2W1RPpXM.js +71 -0
  4. package/.output/public/_nuxt/{C4pxqdgg.js → 5UFq_rDn.js} +1 -1
  5. package/.output/public/_nuxt/5Zh-9l8_.js +1 -0
  6. package/.output/public/_nuxt/{DK9jxJ0g.js → 90UksHlj.js} +1 -1
  7. package/.output/public/_nuxt/{9IQmsEjr.js → 9QKmiSP_.js} +1 -1
  8. package/.output/public/_nuxt/{BOj6t-oo.js → ARbTpeGy.js} +1 -1
  9. package/.output/public/_nuxt/{DyRelyfs.js → ApfLnl06.js} +1 -1
  10. package/.output/public/_nuxt/{DznawRFW.js → B-2BuR5g.js} +1 -1
  11. package/.output/public/_nuxt/B4u7Mczo.js +1 -0
  12. package/.output/public/_nuxt/{DAQhmSv4.js → B5dI_yLq.js} +1 -1
  13. package/.output/public/_nuxt/{Bm9LyG4F.js → B6fnZcA6.js} +1 -1
  14. package/.output/public/_nuxt/{9QnH0xQM.js → B7uMSBlN.js} +1 -1
  15. package/.output/public/_nuxt/BBiRyPlN.js +1 -0
  16. package/.output/public/_nuxt/{iBGCpHdw.js → BF7413u4.js} +2 -2
  17. package/.output/public/_nuxt/{4MiwzAAt.js → BGtUoCgi.js} +2 -2
  18. package/.output/public/_nuxt/{CxuZBC8n.js → BHe4VLtR.js} +1 -1
  19. package/.output/public/_nuxt/{D3RiUGdz.js → BIMBp1Tj.js} +1 -1
  20. package/.output/public/_nuxt/{g20UHUCv.js → BIvPdoE3.js} +1 -1
  21. package/.output/public/_nuxt/BKaRtCjP.js +1 -0
  22. package/.output/public/_nuxt/BLmc9T7l.js +1 -0
  23. package/.output/public/_nuxt/BMdnU6BF.js +1 -0
  24. package/.output/public/_nuxt/{CKkC3Ptm.js → BOgdaA_8.js} +1 -1
  25. package/.output/public/_nuxt/{BffWCM73.js → BQZfTrUg.js} +1 -1
  26. package/.output/public/_nuxt/BQnublTW.js +1 -0
  27. package/.output/public/_nuxt/BSsvedap.js +1 -0
  28. package/.output/public/_nuxt/{Ci7UEZQh.js → BVypxKRT.js} +1 -1
  29. package/.output/public/_nuxt/{CYP_MLH8.js → BWqJFnZy.js} +1 -1
  30. package/.output/public/_nuxt/BXxYdXMr.js +1 -0
  31. package/.output/public/_nuxt/{D_3Rq1BS.js → B_17gAr_.js} +1 -1
  32. package/.output/public/_nuxt/B_qzFVK_.js +1 -0
  33. package/.output/public/_nuxt/{BqKFIuRj.js → BbRPwpIX.js} +1 -1
  34. package/.output/public/_nuxt/BhrzKbv9.js +1 -0
  35. package/.output/public/_nuxt/{Cqy_L_ip.js → Bl6LNGlA.js} +1 -1
  36. package/.output/public/_nuxt/{Fukkqjkf.js → BlPToGni.js} +1 -1
  37. package/.output/public/_nuxt/{DHKLCQRG.js → BlwHr46F.js} +1 -1
  38. package/.output/public/_nuxt/{C6aqGHu1.js → BnmwiZbF.js} +1 -1
  39. package/.output/public/_nuxt/BqtxLJaf.js +1 -0
  40. package/.output/public/_nuxt/{eko-0FUm.js → BrEXdify.js} +1 -1
  41. package/.output/public/_nuxt/{D3e44mCL.js → BtNnS4m3.js} +1 -1
  42. package/.output/public/_nuxt/{BCtfQCzC.js → BtVIBBUN.js} +1 -1
  43. package/.output/public/_nuxt/Bw5h4Jaf.js +1 -0
  44. package/.output/public/_nuxt/{FvlxxmNk.js → Bwcpy7gC.js} +2 -2
  45. package/.output/public/_nuxt/{Db2v8O7O.js → C0TUK31m.js} +1 -1
  46. package/.output/public/_nuxt/C1T4GK6c.js +1 -0
  47. package/.output/public/_nuxt/C2ANDZen.js +1 -0
  48. package/.output/public/_nuxt/{CqU2XbzO.js → C2RZSTuy.js} +1 -1
  49. package/.output/public/_nuxt/C3dYlP5x.js +1 -0
  50. package/.output/public/_nuxt/{m5kGCDpI.js → C3sh_tLi.js} +3 -3
  51. package/.output/public/_nuxt/{BjjCvHLT.js → C4zyxZG7.js} +1 -1
  52. package/.output/public/_nuxt/{C3FxIITy.js → C5I-XBZT.js} +1 -1
  53. package/.output/public/_nuxt/{yuf23kh9.js → CC4Goztu.js} +1 -1
  54. package/.output/public/_nuxt/CC77iplr.js +1 -0
  55. package/.output/public/_nuxt/{xuzLdW-o.js → CFyD2NHP.js} +1 -1
  56. package/.output/public/_nuxt/{CsJ9KhQ4.js → CGQDTeaO.js} +1 -1
  57. package/.output/public/_nuxt/{DnjGH3SQ.js → CHpwuMSk.js} +1 -1
  58. package/.output/public/_nuxt/CLzcRUcs.js +1 -0
  59. package/.output/public/_nuxt/CM2phu_3.js +1 -0
  60. package/.output/public/_nuxt/{Cr8ixbr1.js → CQpYRq61.js} +1 -1
  61. package/.output/public/_nuxt/{C0JKNMDO.js → CUN4bYcg.js} +1 -1
  62. package/.output/public/_nuxt/{CmzH6R-N.js → CXoITXft.js} +19 -19
  63. package/.output/public/_nuxt/CYjcQPl-.js +1 -0
  64. package/.output/public/_nuxt/{DGX0tzL8.js → CZ32KfaS.js} +1 -1
  65. package/.output/public/_nuxt/CclZMdca.js +1 -0
  66. package/.output/public/_nuxt/{C69W7k2j.js → CdpT_Vb6.js} +1 -1
  67. package/.output/public/_nuxt/CflRLvFC.js +1 -0
  68. package/.output/public/_nuxt/{gBC9k4Qj.js → CkqNv7sq.js} +2 -2
  69. package/.output/public/_nuxt/ClXDAYjE.js +1 -0
  70. package/.output/public/_nuxt/CrZGoMo_.js +1 -0
  71. package/.output/public/_nuxt/{BZXMQuYP.js → CvJtd2Af.js} +1 -1
  72. package/.output/public/_nuxt/{DKZxeXDQ.js → Cwtd8e-P.js} +1 -1
  73. package/.output/public/_nuxt/{nIU2F7ia.js → Cx44SSNp.js} +3 -3
  74. package/.output/public/_nuxt/{BzOqrmGa.js → CxEVzuCn.js} +3 -3
  75. package/.output/public/_nuxt/{Dy_Cq5LQ.js → CzIMQevQ.js} +1 -1
  76. package/.output/public/_nuxt/{D6t3dcTl.js → D0P9llU7.js} +1 -1
  77. package/.output/public/_nuxt/{JJ3634gV.js → D1DYuOOm.js} +1 -1
  78. package/.output/public/_nuxt/{BAIz-dEB.js → D1dDc8Vw.js} +1 -1
  79. package/.output/public/_nuxt/{DSRrg8JT.js → D1r0uqf3.js} +1 -1
  80. package/.output/public/_nuxt/{CNnJrDvu.js → D3a8R1T6.js} +1 -1
  81. package/.output/public/_nuxt/{B1X4Bzcy.js → D5EZbuub.js} +1 -1
  82. package/.output/public/_nuxt/D9V13KTK.js +1 -0
  83. package/.output/public/_nuxt/DAE2hbP7.js +1 -0
  84. package/.output/public/_nuxt/{Cvp7FI3T.js → DAIbdyS6.js} +1 -1
  85. package/.output/public/_nuxt/{EuOqK1A6.js → DAvlXjt0.js} +1 -1
  86. package/.output/public/_nuxt/DBKzwexZ.js +1 -0
  87. package/.output/public/_nuxt/{wCGVE8_e.js → DEATxnaF.js} +1 -1
  88. package/.output/public/_nuxt/{cABRLVee.js → DFg8PvHV.js} +1 -1
  89. package/.output/public/_nuxt/DM4MyqI-.js +1 -0
  90. package/.output/public/_nuxt/{Cdt3I3Go.js → DNE7kw9s.js} +1 -1
  91. package/.output/public/_nuxt/DO0oG4fG.js +1 -0
  92. package/.output/public/_nuxt/{B6S_ob86.js → DPFugPaB.js} +1 -1
  93. package/.output/public/_nuxt/{DJjDvbZE.js → DQlXU6_H.js} +1 -1
  94. package/.output/public/_nuxt/DQvuQpwh.js +1 -0
  95. package/.output/public/_nuxt/{sf57orEk.js → DRlG_bnX.js} +1 -1
  96. package/.output/public/_nuxt/{C6RC3lA1.js → DSQj-oMk.js} +1 -1
  97. package/.output/public/_nuxt/{CeIVm4A3.js → DU6ewLkE.js} +1 -1
  98. package/.output/public/_nuxt/{Cp2MA0cm.js → DWhzQg7B.js} +1 -1
  99. package/.output/public/_nuxt/{DJMS2og1.js → D_vK6VPK.js} +1 -1
  100. package/.output/public/_nuxt/{CihWZmJe.js → DaBp0Gba.js} +2 -2
  101. package/.output/public/_nuxt/DaH2FbAy.js +1 -0
  102. package/.output/public/_nuxt/{CtYFj7k1.js → DaJo0CeV.js} +1 -1
  103. package/.output/public/_nuxt/DauLdT7p.js +1 -0
  104. package/.output/public/_nuxt/{DG-T44jj.js → DdPA4eTX.js} +1 -1
  105. package/.output/public/_nuxt/{YuTZB7sD.js → DeAGWdWK.js} +1 -1
  106. package/.output/public/_nuxt/{CitkKxhw.js → DfF1qofg.js} +1 -1
  107. package/.output/public/_nuxt/{Daz4MeL6.js → DiGBA-aA.js} +1 -1
  108. package/.output/public/_nuxt/DiJxF69i.js +1 -0
  109. package/.output/public/_nuxt/{DIoI0uJm.js → DkBIU-1F.js} +1 -1
  110. package/.output/public/_nuxt/DmAM6bZ0.js +1 -0
  111. package/.output/public/_nuxt/DmeAKr3J.js +1 -0
  112. package/.output/public/_nuxt/DmmTnMzZ.js +1 -0
  113. package/.output/public/_nuxt/{Lwdv_RKd.js → DqsUSndS.js} +1 -1
  114. package/.output/public/_nuxt/Dvw-hR3Y.js +1 -0
  115. package/.output/public/_nuxt/{CVgTJeSq.js → Dz6sfh81.js} +1 -1
  116. package/.output/public/_nuxt/{BYjadNrw.js → FNhYm5FX.js} +1 -1
  117. package/.output/public/_nuxt/{Nb2jBtYT.js → HOeKUnra.js} +1 -1
  118. package/.output/public/_nuxt/{CtchsY6e.js → IR1jkN7B.js} +1 -1
  119. package/.output/public/_nuxt/{DCzfkCGa.js → MpTk6K7N.js} +1 -1
  120. package/.output/public/_nuxt/NZ7Wz6LP.js +1 -0
  121. package/.output/public/_nuxt/{DfQu3kEw.js → PqWbiAD2.js} +1 -1
  122. package/.output/public/_nuxt/{Jez9DHn7.js → Tu4FhMRc.js} +1 -1
  123. package/.output/public/_nuxt/{B3y_Qqox.js → UKPXYG4z.js} +1 -1
  124. package/.output/public/_nuxt/{BlAZO7nq.js → UO2Y9Nve.js} +1 -1
  125. package/.output/public/_nuxt/{KKK6HVeG.js → XHiJSquP.js} +1 -1
  126. package/.output/public/_nuxt/YGWAImQo.js +1 -0
  127. package/.output/public/_nuxt/{ghuJ76mD.js → ZR87XvwB.js} +1 -1
  128. package/.output/public/_nuxt/{yNrp2XvX.js → _E89BQAO.js} +1 -1
  129. package/.output/public/_nuxt/{C_BdYLzz.js → aiXk7zRt.js} +1 -1
  130. package/.output/public/_nuxt/builds/latest.json +1 -1
  131. package/.output/public/_nuxt/builds/meta/91727fcc-bf7f-407f-9b1e-092017fcfee0.json +1 -0
  132. package/.output/public/_nuxt/cL7whuPe.js +1 -0
  133. package/.output/public/_nuxt/{BasgsT_S.js → ct6_k5IW.js} +1 -1
  134. package/.output/public/_nuxt/entry._7ZkP07A.css +1 -0
  135. package/.output/public/_nuxt/{DTDgHTuh.js → fEUQvmn8.js} +2 -2
  136. package/.output/public/_nuxt/{FNC8XZTk.js → gGlaVUMD.js} +1 -1
  137. package/.output/public/_nuxt/gjmGkVlL.js +1 -0
  138. package/.output/public/_nuxt/{IRSbVPIu.js → m5001Uvl.js} +1 -1
  139. package/.output/public/_nuxt/{_CYZi8HN.js → mQkFCz_M.js} +1 -1
  140. package/.output/public/_nuxt/{BxXOsXrM.js → p9l1LjVc.js} +10 -10
  141. package/.output/public/_nuxt/{BsEZoHd1.js → qR_K5W8V.js} +1 -1
  142. package/.output/public/_nuxt/{BrNqhp1a.js → t_9QQ4MF.js} +7 -7
  143. package/.output/public/_nuxt/{pcUI-zuY.js → uc4c4mfb.js} +1 -1
  144. package/.output/public/_nuxt/{usage.vakN1lvi.css → usage.BDeyCZwW.css} +1 -1
  145. package/.output/public/_nuxt/wPSLEMBw.js +1 -0
  146. package/.output/public/_nuxt/xKRwul0f.js +1 -0
  147. package/.output/public/_nuxt/{BWhMnjID.js → xgpiGSxb.js} +1 -1
  148. package/.output/public/_nuxt/xxnk7j0F.js +1 -0
  149. package/.output/public/favicon.svg +1 -0
  150. package/.output/server/chunks/build/A-BWukSPjS.mjs +1 -0
  151. package/.output/server/chunks/build/Accordion-BaJYea6e.mjs +1 -0
  152. package/.output/server/chunks/build/AccordionItem-DdG2zgcN.mjs +1 -0
  153. package/.output/server/chunks/build/Badge-BrU9UkCv.mjs +1 -0
  154. package/.output/server/chunks/build/Blockquote-DND8wTkU.mjs +1 -0
  155. package/.output/server/chunks/build/Callout-1halpaEg.mjs +1 -0
  156. package/.output/server/chunks/build/Card-BHCSDKDt.mjs +1 -0
  157. package/.output/server/chunks/build/CardGroup-BOuJcNGp.mjs +1 -0
  158. package/.output/server/chunks/build/Caution-BP3y-TcC.mjs +1 -0
  159. package/.output/server/chunks/build/Code-B1xkAS5a.mjs +1 -0
  160. package/.output/server/chunks/build/CodeCollapse-BIhaNa22.mjs +1 -0
  161. package/.output/server/chunks/build/CodeGroup-BviYyCuo.mjs +1 -0
  162. package/.output/server/chunks/build/CodeIcon-CWD5HcV7.mjs +2 -1
  163. package/.output/server/chunks/build/CodePreview-D8PsCQ6m.mjs +1 -0
  164. package/.output/server/chunks/build/CodeTree-BUTLupmL.mjs +1 -0
  165. package/.output/server/chunks/build/Collapsible-BIvXNaSq.mjs +1 -0
  166. package/.output/server/chunks/build/DropdownMenu-BBrV9nXz.mjs +1 -1
  167. package/.output/server/chunks/build/EditorToolbar-DIfb5arC.mjs +1 -1
  168. package/.output/server/chunks/build/Em-DsIz_BnD.mjs +1 -0
  169. package/.output/server/chunks/build/Field-cwwmSQDT.mjs +1 -0
  170. package/.output/server/chunks/build/FieldGroup-CAIpQv8s.mjs +1 -0
  171. package/.output/server/chunks/build/H1-BbFNsPyP.mjs +1 -0
  172. package/.output/server/chunks/build/H2-vHTl_pWr.mjs +1 -0
  173. package/.output/server/chunks/build/H3-7eTcfO3s.mjs +1 -0
  174. package/.output/server/chunks/build/H4-C89p_PKO.mjs +1 -0
  175. package/.output/server/chunks/build/Hr-Bm8RlL3O.mjs +1 -0
  176. package/.output/server/chunks/build/Icon-Dp9iy0BI.mjs +1 -0
  177. package/.output/server/chunks/build/Img-CWLmvN1t.mjs +2 -1
  178. package/.output/server/chunks/build/Kbd-CQG6I_Ch.mjs +1 -0
  179. package/.output/server/chunks/build/Li-Bw1QUaGv.mjs +1 -0
  180. package/.output/server/chunks/build/MDC-Dx0YPDhe.mjs +1 -1
  181. package/.output/server/chunks/build/Note-CHkjm9jm.mjs +1 -0
  182. package/.output/server/chunks/build/Ol-D-fPnfFM.mjs +1 -0
  183. package/.output/server/chunks/build/P-B5YI1V9y.mjs +1 -0
  184. package/.output/server/chunks/build/Pre-ChiJcf3C.mjs +1 -0
  185. package/.output/server/chunks/build/ProseH5-DahJyv8h.mjs +1 -0
  186. package/.output/server/chunks/build/ProseH6-C4Is5h6c.mjs +1 -0
  187. package/.output/server/chunks/build/Select-BB1oLrCD.mjs +1 -1
  188. package/.output/server/chunks/build/SelectMenu-DPssg6zD.mjs +1 -1
  189. package/.output/server/chunks/build/Steps-BZpvXfzb.mjs +1 -0
  190. package/.output/server/chunks/build/Strong-DXJqOWL3.mjs +1 -0
  191. package/.output/server/chunks/build/Table-BSrLZ7dt.mjs +1 -0
  192. package/.output/server/chunks/build/Table-DCwTlhCj.mjs +1 -1
  193. package/.output/server/chunks/build/Tabs-Dk3nvOFF.mjs +1 -0
  194. package/.output/server/chunks/build/TabsItem-CDhyuBtJ.mjs +1 -0
  195. package/.output/server/chunks/build/Tbody-CjMT5oH-.mjs +1 -0
  196. package/.output/server/chunks/build/Td-ZBVaEjFN.mjs +1 -0
  197. package/.output/server/chunks/build/Th-D317icbd.mjs +1 -0
  198. package/.output/server/chunks/build/Thead-Ca_ZESTK.mjs +1 -0
  199. package/.output/server/chunks/build/Tip-CP3oTARR.mjs +1 -0
  200. package/.output/server/chunks/build/Tooltip-TRyl6dje.mjs +1 -1
  201. package/.output/server/chunks/build/Tr-6jI8j9gD.mjs +1 -0
  202. package/.output/server/chunks/build/{docs-Dk2JnYq3.mjs → Tree-DUhXKd8y.mjs} +46 -2235
  203. package/.output/server/chunks/build/Tree-DUhXKd8y.mjs.map +1 -0
  204. package/.output/server/chunks/build/Ul-BUGj_CPb.mjs +1 -0
  205. package/.output/server/chunks/build/Warning-BJ8G6cxC.mjs +1 -0
  206. package/.output/server/chunks/build/_id_-DN00UDdO.mjs +1 -0
  207. package/.output/server/chunks/build/_id_-DN00UDdO.mjs.map +1 -1
  208. package/.output/server/chunks/build/_name_-BnS_KEfX.mjs +1592 -0
  209. package/.output/server/chunks/build/_name_-BnS_KEfX.mjs.map +1 -0
  210. package/.output/server/chunks/build/{_uuid_-0UgdUhfY.mjs → _uuid_-DfJaumTE.mjs} +5 -4
  211. package/.output/server/chunks/build/{_uuid_-0UgdUhfY.mjs.map → _uuid_-DfJaumTE.mjs.map} +1 -1
  212. package/.output/server/chunks/build/auth-BGPNH2QJ.mjs +20 -0
  213. package/.output/server/chunks/build/auth-BGPNH2QJ.mjs.map +1 -0
  214. package/.output/server/chunks/build/auth-CvD7MqKW.mjs +1 -0
  215. package/.output/server/chunks/build/auth-CvD7MqKW.mjs.map +1 -1
  216. package/.output/server/chunks/build/chat-CZMiB68R.mjs +1 -0
  217. package/.output/server/chunks/build/chat-CZMiB68R.mjs.map +1 -1
  218. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  219. package/.output/server/chunks/build/cookie-C_iulBi6.mjs +1 -1
  220. package/.output/server/chunks/build/{dashboard-YEscLBQN.mjs → dashboard-CLk1NlbR.mjs} +15 -4
  221. package/.output/server/chunks/build/dashboard-CLk1NlbR.mjs.map +1 -0
  222. package/.output/server/chunks/build/{dashboard-CpMVYnDV.mjs → dashboard-CiVTAZuF.mjs} +12 -4
  223. package/.output/server/chunks/build/{dashboard-CpMVYnDV.mjs.map → dashboard-CiVTAZuF.mjs.map} +1 -1
  224. package/.output/server/chunks/build/docs-ChGwOPg5.mjs +2204 -0
  225. package/.output/server/chunks/build/docs-ChGwOPg5.mjs.map +1 -0
  226. package/.output/server/chunks/build/error-404-BzbcNcdU.mjs +1 -0
  227. package/.output/server/chunks/build/error-500-uCDjGRW8.mjs +1 -0
  228. package/.output/server/chunks/build/fetch-BB7Qzkwe.mjs +1 -1
  229. package/.output/server/chunks/build/{hooks-DP8WoUPS.mjs → hooks-D328DcO6.mjs} +3 -2
  230. package/.output/server/chunks/build/hooks-D328DcO6.mjs.map +1 -0
  231. package/.output/server/chunks/build/{index-DVx-QlhP.mjs → index-Byt-3Yq6.mjs} +3 -2
  232. package/.output/server/chunks/build/{index-DVx-QlhP.mjs.map → index-Byt-3Yq6.mjs.map} +1 -1
  233. package/.output/server/chunks/build/{index-Ba_bPJgk.mjs → index-C9PuieXh.mjs} +3 -2
  234. package/.output/server/chunks/build/index-C9PuieXh.mjs.map +1 -0
  235. package/.output/server/chunks/build/index-C_LcBBgO.mjs +1508 -0
  236. package/.output/server/chunks/build/index-C_LcBBgO.mjs.map +1 -0
  237. package/.output/server/chunks/build/index-CxDxc9fm.mjs +1 -1
  238. package/.output/server/chunks/build/index-DzdvIi8V.mjs +1 -0
  239. package/.output/server/chunks/build/library-CbWcF5wT.mjs +601 -0
  240. package/.output/server/chunks/build/library-CbWcF5wT.mjs.map +1 -0
  241. package/.output/server/chunks/build/{login-BAysbpyX.mjs → login-DnnElTl2.mjs} +15 -7
  242. package/.output/server/chunks/build/{login-BAysbpyX.mjs.map → login-DnnElTl2.mjs.map} +1 -1
  243. package/.output/server/chunks/build/memories-BqA719O1.mjs +1 -0
  244. package/.output/server/chunks/build/memories-BqA719O1.mjs.map +1 -1
  245. package/.output/server/chunks/build/server.mjs +62 -34
  246. package/.output/server/chunks/build/server.mjs.map +1 -1
  247. package/.output/server/chunks/build/settings-DdkKCJ00.mjs +1 -0
  248. package/.output/server/chunks/build/settings-DdkKCJ00.mjs.map +1 -1
  249. package/.output/server/chunks/build/styles.mjs +2 -2
  250. package/.output/server/chunks/build/{tasks-DiOi1HG_.mjs → tasks-DnAFqbtt.mjs} +3 -2
  251. package/.output/server/chunks/build/tasks-DnAFqbtt.mjs.map +1 -0
  252. package/.output/server/chunks/build/{usage-H_mcd_fz.mjs → usage-CSrBh4Or.mjs} +159 -44
  253. package/.output/server/chunks/build/{usage-H_mcd_fz.mjs.map → usage-CSrBh4Or.mjs.map} +1 -1
  254. package/.output/server/chunks/build/{usePreferences-CzC8fRzd.mjs → usePreferences-DH1QjxOj.mjs} +7 -1
  255. package/.output/server/chunks/build/usePreferences-DH1QjxOj.mjs.map +1 -0
  256. package/.output/server/chunks/build/{view-Dc8mvzCB.mjs → view-n2sYa4Zh.mjs} +4 -3
  257. package/.output/server/chunks/build/{view-Dc8mvzCB.mjs.map → view-n2sYa4Zh.mjs.map} +1 -1
  258. package/.output/server/chunks/build/virtual_nuxt__Users_tony_Documents_GitHub_second-brain_node_modules_.cache_nuxt_.nuxt_mdc-imports-PtwWlZ2H.mjs +1 -0
  259. package/.output/server/chunks/nitro/nitro.mjs +1247 -824
  260. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  261. package/.output/server/chunks/routes/_ws/chat.mjs +2 -1
  262. package/.output/server/chunks/routes/_ws/chat.mjs.map +1 -1
  263. package/.output/server/chunks/routes/api/agents/_id/cancel.post.mjs +1 -0
  264. package/.output/server/chunks/routes/api/agents/_id/cancel.post.mjs.map +1 -1
  265. package/.output/server/chunks/routes/api/agents/_id/run.post.mjs +1 -0
  266. package/.output/server/chunks/routes/api/agents/_id/run.post.mjs.map +1 -1
  267. package/.output/server/chunks/routes/api/agents/_id/runs.get.mjs +1 -0
  268. package/.output/server/chunks/routes/api/agents/_id/runs.get.mjs.map +1 -1
  269. package/.output/server/chunks/routes/api/agents/_id/stats.get.mjs +1 -0
  270. package/.output/server/chunks/routes/api/agents/_id/stats.get.mjs.map +1 -1
  271. package/.output/server/chunks/routes/api/agents/_id_.delete.mjs +1 -0
  272. package/.output/server/chunks/routes/api/agents/_id_.delete.mjs.map +1 -1
  273. package/.output/server/chunks/routes/api/agents/_id_.get.mjs +1 -0
  274. package/.output/server/chunks/routes/api/agents/_id_.get.mjs.map +1 -1
  275. package/.output/server/chunks/routes/api/agents/_id_.patch.mjs +1 -0
  276. package/.output/server/chunks/routes/api/agents/_id_.patch.mjs.map +1 -1
  277. package/.output/server/chunks/routes/api/agents/stats.get.mjs +1 -0
  278. package/.output/server/chunks/routes/api/agents/stats.get.mjs.map +1 -1
  279. package/.output/server/chunks/routes/api/auth/_...all_.mjs +1 -0
  280. package/.output/server/chunks/routes/api/auth/_...all_.mjs.map +1 -1
  281. package/.output/server/chunks/routes/api/conversations/_id_.delete.mjs +1 -0
  282. package/.output/server/chunks/routes/api/conversations/_id_.delete.mjs.map +1 -1
  283. package/.output/server/chunks/routes/api/conversations/_id_.get.mjs +1 -0
  284. package/.output/server/chunks/routes/api/conversations/_id_.get.mjs.map +1 -1
  285. package/.output/server/chunks/routes/api/dashboard/overview.get.mjs +1 -0
  286. package/.output/server/chunks/routes/api/dashboard/overview.get.mjs.map +1 -1
  287. package/.output/server/chunks/routes/api/documents/_id/public.get.mjs +1 -0
  288. package/.output/server/chunks/routes/api/documents/_id/public.get.mjs.map +1 -1
  289. package/.output/server/chunks/routes/api/documents/_id/restore.post.mjs +1 -0
  290. package/.output/server/chunks/routes/api/documents/_id/restore.post.mjs.map +1 -1
  291. package/.output/server/chunks/routes/api/documents/by-path.post.mjs +1 -0
  292. package/.output/server/chunks/routes/api/documents/by-path.post.mjs.map +1 -1
  293. package/.output/server/chunks/routes/api/documents/index.delete.mjs +1 -0
  294. package/.output/server/chunks/routes/api/documents/index.delete.mjs.map +1 -1
  295. package/.output/server/chunks/routes/api/documents/index.put.mjs +1 -0
  296. package/.output/server/chunks/routes/api/documents/index.put.mjs.map +1 -1
  297. package/.output/server/chunks/routes/api/fs/delete.post.mjs +1 -0
  298. package/.output/server/chunks/routes/api/fs/delete.post.mjs.map +1 -1
  299. package/.output/server/chunks/routes/api/fs/list.get.mjs +1 -0
  300. package/.output/server/chunks/routes/api/fs/list.get.mjs.map +1 -1
  301. package/.output/server/chunks/routes/api/fs/mkdir.post.mjs +1 -0
  302. package/.output/server/chunks/routes/api/fs/mkdir.post.mjs.map +1 -1
  303. package/.output/server/chunks/routes/api/fs/move.post.mjs +1 -0
  304. package/.output/server/chunks/routes/api/fs/move.post.mjs.map +1 -1
  305. package/.output/server/chunks/routes/api/fs/read.post.mjs +1 -0
  306. package/.output/server/chunks/routes/api/fs/read.post.mjs.map +1 -1
  307. package/.output/server/chunks/routes/api/fs/rename.post.mjs +1 -0
  308. package/.output/server/chunks/routes/api/fs/rename.post.mjs.map +1 -1
  309. package/.output/server/chunks/routes/api/fs/write.post.mjs +1 -0
  310. package/.output/server/chunks/routes/api/fs/write.post.mjs.map +1 -1
  311. package/.output/server/chunks/routes/api/health.get.mjs +1 -0
  312. package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
  313. package/.output/server/chunks/routes/api/home.get.mjs +1 -0
  314. package/.output/server/chunks/routes/api/home.get.mjs.map +1 -1
  315. package/.output/server/chunks/routes/api/hooks/index.get.mjs +1 -0
  316. package/.output/server/chunks/routes/api/hooks/index.get.mjs.map +1 -1
  317. package/.output/server/chunks/routes/api/hooks/index.post.mjs +1 -0
  318. package/.output/server/chunks/routes/api/hooks/index.post.mjs.map +1 -1
  319. package/.output/server/chunks/routes/api/hooks/stats.get.mjs +1 -0
  320. package/.output/server/chunks/routes/api/hooks/stats.get.mjs.map +1 -1
  321. package/.output/server/chunks/routes/api/index.get.mjs +1 -0
  322. package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
  323. package/.output/server/chunks/routes/api/index.get2.mjs +1 -0
  324. package/.output/server/chunks/routes/api/index.get2.mjs.map +1 -1
  325. package/.output/server/chunks/routes/api/index.get3.mjs +1 -0
  326. package/.output/server/chunks/routes/api/index.get3.mjs.map +1 -1
  327. package/.output/server/chunks/routes/api/index.get4.mjs +1 -0
  328. package/.output/server/chunks/routes/api/index.get4.mjs.map +1 -1
  329. package/.output/server/chunks/routes/api/index.get5.mjs +1 -0
  330. package/.output/server/chunks/routes/api/index.get5.mjs.map +1 -1
  331. package/.output/server/chunks/routes/api/index.get6.mjs +1 -0
  332. package/.output/server/chunks/routes/api/index.get6.mjs.map +1 -1
  333. package/.output/server/chunks/routes/api/index.get7.mjs +40 -38
  334. package/.output/server/chunks/routes/api/index.get7.mjs.map +1 -1
  335. package/.output/server/chunks/routes/api/index.get8.mjs +33 -38
  336. package/.output/server/chunks/routes/api/index.get8.mjs.map +1 -1
  337. package/.output/server/chunks/routes/api/index.get9.mjs +83 -0
  338. package/.output/server/chunks/routes/api/index.get9.mjs.map +1 -0
  339. package/.output/server/chunks/routes/api/index.post.mjs +1 -0
  340. package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
  341. package/.output/server/chunks/routes/api/index.post2.mjs +1 -0
  342. package/.output/server/chunks/routes/api/index.post2.mjs.map +1 -1
  343. package/.output/server/chunks/routes/api/index.post3.mjs +1 -0
  344. package/.output/server/chunks/routes/api/index.post3.mjs.map +1 -1
  345. package/.output/server/chunks/routes/api/index.post4.mjs +1 -0
  346. package/.output/server/chunks/routes/api/index.post4.mjs.map +1 -1
  347. package/.output/server/chunks/routes/api/index.put.mjs +1 -0
  348. package/.output/server/chunks/routes/api/index.put.mjs.map +1 -1
  349. package/.output/server/chunks/routes/api/memory/_id_.delete.mjs +1 -0
  350. package/.output/server/chunks/routes/api/memory/_id_.delete.mjs.map +1 -1
  351. package/.output/server/chunks/routes/api/memory/context.get.mjs +1 -0
  352. package/.output/server/chunks/routes/api/memory/context.get.mjs.map +1 -1
  353. package/.output/server/chunks/routes/api/memory/extract.post.mjs +2 -1
  354. package/.output/server/chunks/routes/api/memory/extract.post.mjs.map +1 -1
  355. package/.output/server/chunks/routes/api/memory/search.get.mjs +1 -0
  356. package/.output/server/chunks/routes/api/memory/search.get.mjs.map +1 -1
  357. package/.output/server/chunks/routes/api/memory/store.post.mjs +1 -0
  358. package/.output/server/chunks/routes/api/memory/store.post.mjs.map +1 -1
  359. package/.output/server/chunks/routes/api/projects/index.delete.mjs +1 -0
  360. package/.output/server/chunks/routes/api/projects/index.delete.mjs.map +1 -1
  361. package/.output/server/chunks/routes/api/projects/index.get.mjs +1 -0
  362. package/.output/server/chunks/routes/api/projects/index.get.mjs.map +1 -1
  363. package/.output/server/chunks/routes/api/projects/index.put.mjs +1 -0
  364. package/.output/server/chunks/routes/api/projects/index.put.mjs.map +1 -1
  365. package/.output/server/chunks/routes/api/secrets/_key_.delete.mjs +1 -0
  366. package/.output/server/chunks/routes/api/secrets/_key_.delete.mjs.map +1 -1
  367. package/.output/server/chunks/routes/api/secrets/_key_.get.mjs +1 -0
  368. package/.output/server/chunks/routes/api/secrets/_key_.get.mjs.map +1 -1
  369. package/.output/server/chunks/routes/api/secrets/_key_.put.mjs +1 -0
  370. package/.output/server/chunks/routes/api/secrets/_key_.put.mjs.map +1 -1
  371. package/.output/server/chunks/routes/api/skills/_name/export.get.mjs +72 -0
  372. package/.output/server/chunks/routes/api/skills/_name/export.get.mjs.map +1 -0
  373. package/.output/server/chunks/routes/api/skills/_name/files/create.post.mjs +73 -0
  374. package/.output/server/chunks/routes/api/skills/_name/files/create.post.mjs.map +1 -0
  375. package/.output/server/chunks/routes/api/skills/_name/files/delete.post.mjs +71 -0
  376. package/.output/server/chunks/routes/api/skills/_name/files/delete.post.mjs.map +1 -0
  377. package/.output/server/chunks/routes/api/skills/_name/files/read.post.mjs +69 -0
  378. package/.output/server/chunks/routes/api/skills/_name/files/read.post.mjs.map +1 -0
  379. package/.output/server/chunks/routes/api/skills/_name/files/write.post.mjs +69 -0
  380. package/.output/server/chunks/routes/api/skills/_name/files/write.post.mjs.map +1 -0
  381. package/.output/server/chunks/routes/api/skills/_name/index.get.mjs +60 -0
  382. package/.output/server/chunks/routes/api/skills/_name/index.get.mjs.map +1 -0
  383. package/.output/server/chunks/routes/api/skills/_name/rename.post.mjs +87 -0
  384. package/.output/server/chunks/routes/api/skills/_name/rename.post.mjs.map +1 -0
  385. package/.output/server/chunks/routes/api/skills/_name/toggle.post.mjs +62 -0
  386. package/.output/server/chunks/routes/api/skills/_name/toggle.post.mjs.map +1 -0
  387. package/.output/server/chunks/routes/api/skills/create.post.mjs +79 -0
  388. package/.output/server/chunks/routes/api/skills/create.post.mjs.map +1 -0
  389. package/.output/server/chunks/routes/api/skills/generate.post.mjs +143 -0
  390. package/.output/server/chunks/routes/api/skills/generate.post.mjs.map +1 -0
  391. package/.output/server/chunks/routes/api/skills/import.post.mjs +96 -0
  392. package/.output/server/chunks/routes/api/skills/import.post.mjs.map +1 -0
  393. package/.output/server/chunks/routes/api/skills/index.get.mjs +82 -0
  394. package/.output/server/chunks/routes/api/skills/index.get.mjs.map +1 -0
  395. package/.output/server/chunks/routes/api/skills/index.get2.mjs +83 -0
  396. package/.output/server/chunks/routes/api/skills/index.get2.mjs.map +1 -0
  397. package/.output/server/chunks/routes/api/skills/library/check-updates.get.mjs +72 -0
  398. package/.output/server/chunks/routes/api/skills/library/check-updates.get.mjs.map +1 -0
  399. package/.output/server/chunks/routes/api/skills/library/install.post.mjs +90 -0
  400. package/.output/server/chunks/routes/api/skills/library/install.post.mjs.map +1 -0
  401. package/.output/server/chunks/routes/api/tasks/_id/restore.post.mjs +1 -0
  402. package/.output/server/chunks/routes/api/tasks/_id/restore.post.mjs.map +1 -1
  403. package/.output/server/chunks/routes/api/tasks/index.delete.mjs +1 -0
  404. package/.output/server/chunks/routes/api/tasks/index.delete.mjs.map +1 -1
  405. package/.output/server/chunks/routes/api/tasks/index.get.mjs +1 -0
  406. package/.output/server/chunks/routes/api/tasks/index.get.mjs.map +1 -1
  407. package/.output/server/chunks/routes/api/tasks/index.put.mjs +1 -0
  408. package/.output/server/chunks/routes/api/tasks/index.put.mjs.map +1 -1
  409. package/.output/server/chunks/routes/api/tasks/tags.get.mjs +1 -0
  410. package/.output/server/chunks/routes/api/tasks/tags.get.mjs.map +1 -1
  411. package/.output/server/chunks/routes/api/usage/stats.get.mjs +4 -1
  412. package/.output/server/chunks/routes/api/usage/stats.get.mjs.map +1 -1
  413. package/.output/server/chunks/routes/api/user/email.patch.mjs +2 -1
  414. package/.output/server/chunks/routes/api/user/email.patch.mjs.map +1 -1
  415. package/.output/server/chunks/routes/notifications.mjs +2 -1
  416. package/.output/server/chunks/routes/notifications.mjs.map +1 -1
  417. package/.output/server/chunks/routes/renderer.mjs +2 -2
  418. package/.output/server/chunks/routes/terminal.mjs +2 -1
  419. package/.output/server/chunks/routes/terminal.mjs.map +1 -1
  420. package/.output/server/index.mjs +2 -1
  421. package/.output/server/index.mjs.map +1 -1
  422. package/.output/server/node_modules/adm-zip/adm-zip.js +949 -0
  423. package/.output/server/node_modules/adm-zip/headers/entryHeader.js +374 -0
  424. package/.output/server/node_modules/adm-zip/headers/index.js +2 -0
  425. package/.output/server/node_modules/adm-zip/headers/mainHeader.js +130 -0
  426. package/.output/server/node_modules/adm-zip/methods/deflater.js +33 -0
  427. package/.output/server/node_modules/adm-zip/methods/index.js +3 -0
  428. package/.output/server/node_modules/adm-zip/methods/inflater.js +34 -0
  429. package/.output/server/node_modules/adm-zip/methods/zipcrypto.js +175 -0
  430. package/.output/server/node_modules/adm-zip/package.json +49 -0
  431. package/.output/server/node_modules/adm-zip/util/constants.js +142 -0
  432. package/.output/server/node_modules/adm-zip/util/decoder.js +5 -0
  433. package/.output/server/node_modules/adm-zip/util/errors.js +63 -0
  434. package/.output/server/node_modules/adm-zip/util/fattr.js +76 -0
  435. package/.output/server/node_modules/adm-zip/util/index.js +5 -0
  436. package/.output/server/node_modules/adm-zip/util/utils.js +336 -0
  437. package/.output/server/node_modules/adm-zip/zipEntry.js +405 -0
  438. package/.output/server/node_modules/adm-zip/zipFile.js +446 -0
  439. package/.output/server/package.json +2 -1
  440. package/Claude/CLAUDE.md +9 -4
  441. package/Claude/skills/environment/SKILL.md +6 -0
  442. package/Claude/skills/memory/SKILL.md +6 -0
  443. package/Claude/skills/project/SKILL.md +6 -0
  444. package/Claude/skills/secret/SKILL.md +85 -0
  445. package/Claude/skills/secret/secret.py +146 -0
  446. package/Claude/skills/skill-creator/SKILL.md +30 -0
  447. package/Claude/skills/task/SKILL.md +6 -0
  448. package/README.md +3 -0
  449. package/app/app.vue +1 -1
  450. package/app/components/dashboard/StatCards.vue +21 -2
  451. package/app/components/skills/Card.vue +82 -0
  452. package/app/components/skills/CreateModal.vue +156 -0
  453. package/app/components/skills/Editor.vue +135 -0
  454. package/app/components/skills/FileTree.vue +336 -0
  455. package/app/components/skills/LibraryCard.vue +122 -0
  456. package/app/components/skills/RenameModal.vue +84 -0
  457. package/app/components/usage/UsageCostChart.client.vue +59 -23
  458. package/app/components/usage/UsageCostChart.server.vue +1 -0
  459. package/app/components/usage/UsageSourceDonut.client.vue +17 -5
  460. package/app/components/usage/UsageSourceDonut.server.vue +1 -0
  461. package/app/components/usage/UsageTopConsumers.vue +13 -3
  462. package/app/composables/usePreferences.ts +9 -1
  463. package/app/layouts/auth.vue +0 -10
  464. package/app/layouts/dashboard.vue +7 -0
  465. package/app/pages/login.vue +18 -8
  466. package/app/pages/skills/[name].vue +210 -0
  467. package/app/pages/skills/index.vue +204 -0
  468. package/app/pages/skills/library.vue +209 -0
  469. package/app/pages/usage.vue +43 -16
  470. package/dist/cli/index.js +35 -36
  471. package/nuxt.config.ts +9 -0
  472. package/package.json +5 -3
  473. package/server/api/skills/[name]/export.get.ts +45 -0
  474. package/server/api/skills/[name]/files/create.post.ts +45 -0
  475. package/server/api/skills/[name]/files/delete.post.ts +45 -0
  476. package/server/api/skills/[name]/files/index.get.ts +28 -0
  477. package/server/api/skills/[name]/files/read.post.ts +41 -0
  478. package/server/api/skills/[name]/files/write.post.ts +42 -0
  479. package/server/api/skills/[name]/index.get.ts +54 -0
  480. package/server/api/skills/[name]/rename.post.ts +64 -0
  481. package/server/api/skills/[name]/toggle.post.ts +32 -0
  482. package/server/api/skills/create.post.ts +51 -0
  483. package/server/api/skills/generate.post.ts +126 -0
  484. package/server/api/skills/import.post.ts +87 -0
  485. package/server/api/skills/index.get.ts +57 -0
  486. package/server/api/skills/library/check-updates.get.ts +46 -0
  487. package/server/api/skills/library/index.get.ts +56 -0
  488. package/server/api/skills/library/install.post.ts +73 -0
  489. package/server/api/usage/stats.get.ts +4 -2
  490. package/server/db/schema.ts +17 -0
  491. package/server/drizzle/migrations/0012_good_deadpool.sql +12 -0
  492. package/server/drizzle/migrations/0013_swift_snowbird.sql +1 -0
  493. package/server/drizzle/migrations/meta/0012_snapshot.json +1713 -0
  494. package/server/drizzle/migrations/meta/0013_snapshot.json +1720 -0
  495. package/server/drizzle/migrations/meta/_journal.json +14 -0
  496. package/server/middleware/auth.ts +0 -1
  497. package/server/plugins/05.skills-catalog.ts +105 -0
  498. package/server/utils/skills-path.ts +197 -0
  499. package/shared/types/index.ts +65 -1
  500. package/.output/public/_nuxt/5ZXA0Ckq.js +0 -1
  501. package/.output/public/_nuxt/BIIJhjQO.js +0 -1
  502. package/.output/public/_nuxt/BIckl6wA.js +0 -1
  503. package/.output/public/_nuxt/BJ3o57WW.js +0 -1
  504. package/.output/public/_nuxt/BNetzZzF.js +0 -1
  505. package/.output/public/_nuxt/BS0ofHJK.js +0 -1
  506. package/.output/public/_nuxt/B_3_hrpn.js +0 -1
  507. package/.output/public/_nuxt/BaBZjmMC.js +0 -1
  508. package/.output/public/_nuxt/BaMqDm5u.js +0 -1
  509. package/.output/public/_nuxt/BhzMoffi.js +0 -1
  510. package/.output/public/_nuxt/BlhFigLL.js +0 -1
  511. package/.output/public/_nuxt/BoIxv-gM.js +0 -1
  512. package/.output/public/_nuxt/Br19oYkq.js +0 -1
  513. package/.output/public/_nuxt/C0kh_F7v.js +0 -1
  514. package/.output/public/_nuxt/C61KgSco.js +0 -1
  515. package/.output/public/_nuxt/CJUdYEdO.js +0 -1
  516. package/.output/public/_nuxt/CVJQGP1Q.js +0 -1
  517. package/.output/public/_nuxt/CWMUi89H.js +0 -1
  518. package/.output/public/_nuxt/Cdu2qGgq.js +0 -1
  519. package/.output/public/_nuxt/CeIu7z4p.js +0 -1
  520. package/.output/public/_nuxt/D2689qk4.js +0 -1
  521. package/.output/public/_nuxt/D31L7Ks6.js +0 -1
  522. package/.output/public/_nuxt/DB359q8R.js +0 -1
  523. package/.output/public/_nuxt/DHG66LPS.js +0 -1
  524. package/.output/public/_nuxt/DJ5V-y_x.js +0 -1
  525. package/.output/public/_nuxt/DLETdGFL.js +0 -1
  526. package/.output/public/_nuxt/DOICd-Ld.js +0 -1
  527. package/.output/public/_nuxt/DPEcH-gi.js +0 -65
  528. package/.output/public/_nuxt/Db8-_gO7.js +0 -1
  529. package/.output/public/_nuxt/DgV-EDJ9.js +0 -1
  530. package/.output/public/_nuxt/Dp2X5R2m.js +0 -1
  531. package/.output/public/_nuxt/DqB723Z0.js +0 -1
  532. package/.output/public/_nuxt/Q8Ps7oN5.js +0 -1
  533. package/.output/public/_nuxt/SXTDhzp6.js +0 -1
  534. package/.output/public/_nuxt/Sg2Lwc46.js +0 -1
  535. package/.output/public/_nuxt/_J_7XIn-.js +0 -1
  536. package/.output/public/_nuxt/builds/meta/a1e9100c-1a4f-4f7e-bb53-9dbe0d07effb.json +0 -1
  537. package/.output/public/_nuxt/entry.CGxIBGAf.css +0 -1
  538. package/.output/public/_nuxt/inmzPrjz.js +0 -1
  539. package/.output/public/_nuxt/oIX-ZDN6.js +0 -1
  540. package/.output/server/chunks/build/auth-CDHRohj4.mjs +0 -77
  541. package/.output/server/chunks/build/auth-CDHRohj4.mjs.map +0 -1
  542. package/.output/server/chunks/build/dashboard-YEscLBQN.mjs.map +0 -1
  543. package/.output/server/chunks/build/docs-Dk2JnYq3.mjs.map +0 -1
  544. package/.output/server/chunks/build/hooks-DP8WoUPS.mjs.map +0 -1
  545. package/.output/server/chunks/build/index-Ba_bPJgk.mjs.map +0 -1
  546. package/.output/server/chunks/build/tasks-DiOi1HG_.mjs.map +0 -1
  547. package/.output/server/chunks/build/usePreferences-CzC8fRzd.mjs.map +0 -1
  548. /package/.output/public/_nuxt/{useCopyToClipboard.Be_IvFWy.css → CodeEditor.Be_IvFWy.css} +0 -0
@@ -0,0 +1,41 @@
1
+ import { readFile, stat } from 'fs/promises'
2
+ import { join, normalize } from 'path'
3
+ import { getSkillsDir, getInactiveSkillsDir } from '~~/server/utils/skills-path'
4
+
5
+ export default defineEventHandler(async (event) => {
6
+ const name = getRouterParam(event, 'name')
7
+ if (!name)
8
+ throw createError({ statusCode: 400, message: 'Skill name required' })
9
+
10
+ const body = await readBody<{ path: string }>(event)
11
+ if (!body?.path)
12
+ throw createError({ statusCode: 400, message: 'File path is required' })
13
+
14
+ const skillDir = await findSkillDir(name)
15
+ if (!skillDir)
16
+ throw createError({ statusCode: 404, message: `Skill '${name}' not found` })
17
+
18
+ // Prevent path traversal
19
+ const filePath = normalize(join(skillDir, body.path))
20
+ if (!filePath.startsWith(skillDir))
21
+ throw createError({ statusCode: 403, message: 'Path traversal not allowed' })
22
+
23
+ const fileStat = await stat(filePath).catch(() => null)
24
+ if (!fileStat?.isFile())
25
+ throw createError({ statusCode: 404, message: 'File not found' })
26
+
27
+ const content = await readFile(filePath, 'utf-8')
28
+ return { data: { path: body.path, content } }
29
+ })
30
+
31
+ async function findSkillDir(name: string): Promise<string | null> {
32
+ const activeDir = join(getSkillsDir(), name)
33
+ const activeStat = await stat(activeDir).catch(() => null)
34
+ if (activeStat?.isDirectory()) return activeDir
35
+
36
+ const inactiveDir = join(getInactiveSkillsDir(), name)
37
+ const inactiveStat = await stat(inactiveDir).catch(() => null)
38
+ if (inactiveStat?.isDirectory()) return inactiveDir
39
+
40
+ return null
41
+ }
@@ -0,0 +1,42 @@
1
+ import { writeFile, mkdir, stat } from 'fs/promises'
2
+ import { join, normalize, dirname } from 'path'
3
+ import { getSkillsDir, getInactiveSkillsDir } from '~~/server/utils/skills-path'
4
+
5
+ export default defineEventHandler(async (event) => {
6
+ const name = getRouterParam(event, 'name')
7
+ if (!name)
8
+ throw createError({ statusCode: 400, message: 'Skill name required' })
9
+
10
+ const body = await readBody<{ path: string, content: string }>(event)
11
+ if (!body?.path)
12
+ throw createError({ statusCode: 400, message: 'File path is required' })
13
+ if (typeof body.content !== 'string')
14
+ throw createError({ statusCode: 400, message: 'Content is required' })
15
+
16
+ const skillDir = await findSkillDir(name)
17
+ if (!skillDir)
18
+ throw createError({ statusCode: 404, message: `Skill '${name}' not found` })
19
+
20
+ // Prevent path traversal
21
+ const filePath = normalize(join(skillDir, body.path))
22
+ if (!filePath.startsWith(skillDir))
23
+ throw createError({ statusCode: 403, message: 'Path traversal not allowed' })
24
+
25
+ // Ensure parent directory exists
26
+ await mkdir(dirname(filePath), { recursive: true })
27
+ await writeFile(filePath, body.content, 'utf-8')
28
+
29
+ return { data: { path: body.path, saved: true } }
30
+ })
31
+
32
+ async function findSkillDir(name: string): Promise<string | null> {
33
+ const activeDir = join(getSkillsDir(), name)
34
+ const activeStat = await stat(activeDir).catch(() => null)
35
+ if (activeStat?.isDirectory()) return activeDir
36
+
37
+ const inactiveDir = join(getInactiveSkillsDir(), name)
38
+ const inactiveStat = await stat(inactiveDir).catch(() => null)
39
+ if (inactiveStat?.isDirectory()) return inactiveDir
40
+
41
+ return null
42
+ }
@@ -0,0 +1,54 @@
1
+ import { readFile, stat } from 'fs/promises'
2
+ import { join } from 'path'
3
+ import { getSkillsDir, getInactiveSkillsDir, parseSkillFrontmatter, buildSkillFileTree, isCoreSkill } from '~~/server/utils/skills-path'
4
+ import type { SkillDetail } from '~~/shared/types'
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
+ // Check active first, then inactive
12
+ const activeDir = join(getSkillsDir(), name)
13
+ const inactiveDir = join(getInactiveSkillsDir(), name)
14
+
15
+ let skillDir = ''
16
+ let active = false
17
+
18
+ const activeStat = await stat(activeDir).catch(() => null)
19
+ if (activeStat?.isDirectory()) {
20
+ skillDir = activeDir
21
+ active = true
22
+ } else {
23
+ const inactiveStat = await stat(inactiveDir).catch(() => null)
24
+ if (inactiveStat?.isDirectory()) {
25
+ skillDir = inactiveDir
26
+ active = false
27
+ }
28
+ }
29
+
30
+ if (!skillDir)
31
+ throw createError({ statusCode: 404, message: `Skill '${name}' not found` })
32
+
33
+ const skillMdPath = join(skillDir, 'SKILL.md')
34
+ const content = await readFile(skillMdPath, 'utf-8').catch(() => '')
35
+ const meta = parseSkillFrontmatter(content)
36
+ const files = await buildSkillFileTree(skillDir)
37
+
38
+ const detail: SkillDetail = {
39
+ name: meta.name || name,
40
+ description: meta.description || '',
41
+ version: meta.version || '',
42
+ author: meta.author || '',
43
+ active,
44
+ core: isCoreSkill(name),
45
+ allowedTools: meta.allowedTools,
46
+ requiresSecrets: meta.requiresSecrets,
47
+ installedFrom: meta.installedFrom || '',
48
+ fileCount: files.filter(f => f.type === 'file').length,
49
+ meta,
50
+ files
51
+ }
52
+
53
+ return { data: detail }
54
+ })
@@ -0,0 +1,64 @@
1
+ import { stat, rename, readFile, writeFile } from 'fs/promises'
2
+ import { join } from 'path'
3
+ import { getSkillsDir, getInactiveSkillsDir, isCoreSkill, validateSkillName } from '~~/server/utils/skills-path'
4
+
5
+ export default defineEventHandler(async (event) => {
6
+ const name = getRouterParam(event, 'name')
7
+ if (!name)
8
+ throw createError({ statusCode: 400, message: 'Skill name required' })
9
+
10
+ if (isCoreSkill(name))
11
+ throw createError({ statusCode: 403, message: `'${name}' is a core skill and cannot be renamed` })
12
+
13
+ const body = await readBody<{ newName: string }>(event)
14
+ if (!body?.newName)
15
+ throw createError({ statusCode: 400, message: 'newName is required' })
16
+
17
+ const nameError = validateSkillName(body.newName)
18
+ if (nameError)
19
+ throw createError({ statusCode: 400, message: nameError })
20
+
21
+ // Find where the skill currently lives
22
+ const activeDir = join(getSkillsDir(), name)
23
+ const inactiveDir = join(getInactiveSkillsDir(), name)
24
+
25
+ let currentDir = ''
26
+ let baseDir = ''
27
+
28
+ const activeStat = await stat(activeDir).catch(() => null)
29
+ if (activeStat?.isDirectory()) {
30
+ currentDir = activeDir
31
+ baseDir = getSkillsDir()
32
+ } else {
33
+ const inactiveStat = await stat(inactiveDir).catch(() => null)
34
+ if (inactiveStat?.isDirectory()) {
35
+ currentDir = inactiveDir
36
+ baseDir = getInactiveSkillsDir()
37
+ }
38
+ }
39
+
40
+ if (!currentDir)
41
+ throw createError({ statusCode: 404, message: `Skill '${name}' not found` })
42
+
43
+ const newDir = join(baseDir, body.newName)
44
+ const newDirStat = await stat(newDir).catch(() => null)
45
+ if (newDirStat)
46
+ throw createError({ statusCode: 409, message: `Skill '${body.newName}' already exists` })
47
+
48
+ // Rename directory
49
+ await rename(currentDir, newDir)
50
+
51
+ // Update name in SKILL.md frontmatter if it exists
52
+ const skillMdPath = join(newDir, 'SKILL.md')
53
+ const content = await readFile(skillMdPath, 'utf-8').catch(() => '')
54
+ if (content) {
55
+ const updated = content.replace(
56
+ /^(name:\s*).+$/m,
57
+ `$1${body.newName}`
58
+ )
59
+ if (updated !== content)
60
+ await writeFile(skillMdPath, updated, 'utf-8')
61
+ }
62
+
63
+ return { data: { name: body.newName } }
64
+ })
@@ -0,0 +1,32 @@
1
+ import { stat, mkdir, rename } from 'fs/promises'
2
+ import { join } from 'path'
3
+ import { getSkillsDir, getInactiveSkillsDir, isCoreSkill } from '~~/server/utils/skills-path'
4
+
5
+ export default defineEventHandler(async (event) => {
6
+ const name = getRouterParam(event, 'name')
7
+ if (!name)
8
+ throw createError({ statusCode: 400, message: 'Skill name required' })
9
+
10
+ if (isCoreSkill(name))
11
+ throw createError({ statusCode: 403, message: `'${name}' is a core skill and cannot be disabled` })
12
+
13
+ const activeDir = join(getSkillsDir(), name)
14
+ const inactiveDir = join(getInactiveSkillsDir(), name)
15
+
16
+ const activeStat = await stat(activeDir).catch(() => null)
17
+ if (activeStat?.isDirectory()) {
18
+ // Move active -> inactive
19
+ await mkdir(getInactiveSkillsDir(), { recursive: true })
20
+ await rename(activeDir, inactiveDir)
21
+ return { data: { name, active: false } }
22
+ }
23
+
24
+ const inactiveStat = await stat(inactiveDir).catch(() => null)
25
+ if (inactiveStat?.isDirectory()) {
26
+ // Move inactive -> active
27
+ await rename(inactiveDir, activeDir)
28
+ return { data: { name, active: true } }
29
+ }
30
+
31
+ throw createError({ statusCode: 404, message: `Skill '${name}' not found` })
32
+ })
@@ -0,0 +1,51 @@
1
+ import { mkdir, writeFile, stat } from 'fs/promises'
2
+ import { join } from 'path'
3
+ import { getSkillsDir, validateSkillName } from '~~/server/utils/skills-path'
4
+
5
+ export default defineEventHandler(async (event) => {
6
+ const body = await readBody<{ name: string, description?: string }>(event)
7
+ if (!body?.name)
8
+ throw createError({ statusCode: 400, message: 'Skill name is required' })
9
+
10
+ const nameError = validateSkillName(body.name)
11
+ if (nameError)
12
+ throw createError({ statusCode: 400, message: nameError })
13
+
14
+ const skillDir = join(getSkillsDir(), body.name)
15
+
16
+ // Check if already exists
17
+ const existing = await stat(skillDir).catch(() => null)
18
+ if (existing)
19
+ throw createError({ statusCode: 409, message: `Skill '${body.name}' already exists` })
20
+
21
+ await mkdir(skillDir, { recursive: true })
22
+
23
+ const description = body.description || `Description for ${body.name}`
24
+
25
+ const skillMd = `---
26
+ name: ${body.name}
27
+ description: ${description}
28
+ allowed-tools: Bash, Read
29
+ metadata:
30
+ version: "1.0.0"
31
+ requires-secrets: []
32
+ author: ""
33
+ repository: ""
34
+ installed-from: ""
35
+ ---
36
+
37
+ # ${body.name}
38
+
39
+ ${description}
40
+
41
+ ## Commands
42
+
43
+ \`\`\`bash
44
+ python3 ~/.claude/skills/${body.name}/${body.name}.py <command>
45
+ \`\`\`
46
+ `
47
+
48
+ await writeFile(join(skillDir, 'SKILL.md'), skillMd, 'utf-8')
49
+
50
+ return { data: { name: body.name, path: skillDir } }
51
+ })
@@ -0,0 +1,126 @@
1
+ import { mkdir, readdir, rm, stat } from 'fs/promises'
2
+ import { join } from 'path'
3
+ import { query } from '@anthropic-ai/claude-agent-sdk'
4
+ import { getInactiveSkillsDir, validateSkillName } from '~~/server/utils/skills-path'
5
+ import { logTokenUsage } from '~~/server/utils/log-token-usage'
6
+
7
+ export default defineEventHandler(async (event) => {
8
+ const body = await readBody<{ name: string, description: string }>(event)
9
+ if (!body?.name || !body?.description)
10
+ throw createError({ statusCode: 400, message: 'name and description are required' })
11
+
12
+ const nameError = validateSkillName(body.name)
13
+ if (nameError)
14
+ throw createError({ statusCode: 400, message: nameError })
15
+
16
+ // Create in inactive-skills so user can review before enabling
17
+ const skillDir = join(getInactiveSkillsDir(), body.name)
18
+
19
+ const existing = await stat(skillDir).catch(() => null)
20
+ if (existing)
21
+ throw createError({ statusCode: 409, message: `Skill '${body.name}' already exists` })
22
+
23
+ await mkdir(skillDir, { recursive: true })
24
+
25
+ const appendInstructions = `You are creating a Claude Code skill called "${body.name}".
26
+ Description: ${body.description}
27
+
28
+ Use the Write tool to create files in the current directory. You MUST create:
29
+ 1. SKILL.md with proper frontmatter (name, description, allowed-tools, metadata with version/requires-secrets/author)
30
+ 2. A Python script if the skill needs to call APIs or run logic
31
+
32
+ CRITICAL RULES:
33
+ - Use the Write tool to create each file
34
+ - NEVER hardcode API keys, tokens, or secrets. Use get_secret() from the shared library.
35
+ - If the skill needs external API keys, list them in metadata.requires-secrets
36
+ - Import the shared client: sys.path.insert(0, str(Path(__file__).parent.parent)); from _lib.api import get, post, get_secret
37
+ - Use argparse for CLI interface
38
+ - Follow existing skill patterns (task.py, memory.py, etc.)
39
+
40
+ SKILL.md frontmatter format:
41
+ ---
42
+ name: ${body.name}
43
+ description: ${body.description}
44
+ allowed-tools: Bash, Read
45
+ metadata:
46
+ version: "1.0.0"
47
+ requires-secrets: []
48
+ author: ""
49
+ repository: ""
50
+ installed-from: ""
51
+ ---`
52
+
53
+ const startTime = Date.now()
54
+ let totalInput = 0
55
+ let totalOutput = 0
56
+ let totalCost = 0
57
+ let turns = 0
58
+
59
+ try {
60
+ const conversation = query({
61
+ prompt: `Create the "${body.name}" skill: ${body.description}`,
62
+ options: {
63
+ systemPrompt: {
64
+ type: 'preset',
65
+ preset: 'claude_code',
66
+ append: appendInstructions
67
+ },
68
+ cwd: skillDir,
69
+ settingSources: ['user'],
70
+ permissionMode: 'bypassPermissions',
71
+ allowDangerouslySkipPermissions: true,
72
+ maxTurns: 30
73
+ }
74
+ })
75
+
76
+ for await (const event of conversation) {
77
+ if (event.type === 'result') {
78
+ // Cast to access usage fields the SDK provides but aren't in the TS types
79
+ const msg = event as unknown as {
80
+ total_cost_usd: number
81
+ num_turns: number
82
+ usage: { input_tokens: number, output_tokens: number }
83
+ }
84
+ totalInput = msg.usage?.input_tokens || 0
85
+ totalOutput = msg.usage?.output_tokens || 0
86
+ totalCost = msg.total_cost_usd || 0
87
+ turns = msg.num_turns || 0
88
+ }
89
+ }
90
+ } catch (e) {
91
+ console.error('[skills/generate] SDK error:', e)
92
+ // Clean up empty directory on failure
93
+ await rm(skillDir, { recursive: true }).catch(() => {})
94
+ throw createError({ statusCode: 500, message: 'Skill generation failed' })
95
+ }
96
+
97
+ // Verify files were actually created
98
+ const files = await readdir(skillDir).catch(() => [])
99
+ if (files.length === 0) {
100
+ await rm(skillDir, { recursive: true }).catch(() => {})
101
+ throw createError({ statusCode: 500, message: 'Skill generation produced no files' })
102
+ }
103
+
104
+ const durationMs = Date.now() - startTime
105
+
106
+ // Log token usage
107
+ await logTokenUsage({
108
+ source: 'agent',
109
+ sourceName: 'Skill Generator',
110
+ inputTokens: totalInput,
111
+ outputTokens: totalOutput,
112
+ costUsd: totalCost,
113
+ durationMs,
114
+ numTurns: turns
115
+ })
116
+
117
+ return {
118
+ data: {
119
+ name: body.name,
120
+ path: skillDir,
121
+ active: false,
122
+ costUsd: totalCost,
123
+ durationMs
124
+ }
125
+ }
126
+ })
@@ -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
+ })
@@ -0,0 +1,57 @@
1
+ import { readdir, readFile, stat } from 'fs/promises'
2
+ import { join } from 'path'
3
+ import { getSkillsDir, getInactiveSkillsDir, parseSkillFrontmatter, isCoreSkill } from '~~/server/utils/skills-path'
4
+ import type { SkillListItem } from '~~/shared/types'
5
+
6
+ export default defineEventHandler(async () => {
7
+ const skills: SkillListItem[] = []
8
+
9
+ // Scan active skills
10
+ await scanDir(getSkillsDir(), true, skills)
11
+
12
+ // Scan inactive skills
13
+ await scanDir(getInactiveSkillsDir(), false, skills)
14
+
15
+ // Sort: core first, then alphabetical
16
+ skills.sort((a, b) => {
17
+ if (a.core !== b.core) return a.core ? -1 : 1
18
+ return a.name.localeCompare(b.name)
19
+ })
20
+
21
+ return { data: skills }
22
+ })
23
+
24
+ async function scanDir(dir: string, active: boolean, skills: SkillListItem[]): Promise<void> {
25
+ const entries = await readdir(dir).catch(() => [])
26
+
27
+ for (const entry of entries) {
28
+ // Skip _lib and hidden dirs
29
+ if (entry.startsWith('_') || entry.startsWith('.'))
30
+ continue
31
+
32
+ const skillDir = join(dir, entry)
33
+ const stats = await stat(skillDir).catch(() => null)
34
+ if (!stats?.isDirectory()) continue
35
+
36
+ const skillMdPath = join(skillDir, 'SKILL.md')
37
+ const content = await readFile(skillMdPath, 'utf-8').catch(() => '')
38
+ const meta = parseSkillFrontmatter(content)
39
+
40
+ // Count files (excluding __pycache__)
41
+ const files = await readdir(skillDir).catch(() => [])
42
+ const fileCount = files.filter(f => f !== '__pycache__' && !f.endsWith('.pyc')).length
43
+
44
+ skills.push({
45
+ name: meta.name || entry,
46
+ description: meta.description || '',
47
+ version: meta.version || '',
48
+ author: meta.author || '',
49
+ active,
50
+ core: isCoreSkill(entry),
51
+ allowedTools: meta.allowedTools,
52
+ requiresSecrets: meta.requiresSecrets,
53
+ installedFrom: meta.installedFrom || '',
54
+ fileCount
55
+ })
56
+ }
57
+ }
@@ -0,0 +1,46 @@
1
+ import { readFile, readdir, stat } from 'fs/promises'
2
+ import { join } from 'path'
3
+ import { getDb } from '~~/server/db'
4
+ import { getSkillsDir, getInactiveSkillsDir, parseSkillFrontmatter } from '~~/server/utils/skills-path'
5
+
6
+ export default defineEventHandler(async () => {
7
+ const db = getDb()
8
+ const catalogItems = await db.query.skillsCatalog.findMany()
9
+
10
+ if (catalogItems.length === 0)
11
+ return { data: { updates: [] } }
12
+
13
+ const catalogByName = new Map(catalogItems.map(c => [c.name, c]))
14
+ const updates: { name: string, installed: string, latest: string }[] = []
15
+
16
+ // Scan both active and inactive skill dirs
17
+ for (const dir of [getSkillsDir(), getInactiveSkillsDir()]) {
18
+ const dirStat = await stat(dir).catch(() => null)
19
+ if (!dirStat) continue
20
+
21
+ const entries = await readdir(dir, { withFileTypes: true })
22
+ for (const entry of entries) {
23
+ if (!entry.isDirectory()) continue
24
+
25
+ const skillMdPath = join(dir, entry.name, 'SKILL.md')
26
+ const content = await readFile(skillMdPath, 'utf-8').catch(() => '')
27
+ if (!content) continue
28
+
29
+ const meta = parseSkillFrontmatter(content)
30
+ if (!meta.installedFrom) continue
31
+
32
+ const catalogEntry = catalogByName.get(entry.name)
33
+ if (!catalogEntry) continue
34
+
35
+ if (meta.version && meta.version !== catalogEntry.version) {
36
+ updates.push({
37
+ name: entry.name,
38
+ installed: meta.version,
39
+ latest: catalogEntry.version
40
+ })
41
+ }
42
+ }
43
+ }
44
+
45
+ return { data: { updates } }
46
+ })
@@ -0,0 +1,56 @@
1
+ import { readFile, stat } from 'fs/promises'
2
+ import { join } from 'path'
3
+ import { getDb } from '~~/server/db'
4
+ import { getSkillsDir, getInactiveSkillsDir, parseSkillFrontmatter } from '~~/server/utils/skills-path'
5
+
6
+ export default defineEventHandler(async () => {
7
+ const db = getDb()
8
+ const catalogItems = await db.query.skillsCatalog.findMany()
9
+
10
+ // Check which skills are already installed
11
+ const skillsDir = getSkillsDir()
12
+ const inactiveDir = getInactiveSkillsDir()
13
+
14
+ const items = await Promise.all(catalogItems.map(async (item) => {
15
+ const activePath = join(skillsDir, item.name, 'SKILL.md')
16
+ const inactivePath = join(inactiveDir, item.name, 'SKILL.md')
17
+
18
+ let installed = false
19
+ let installedVersion: string | undefined
20
+
21
+ // Check active skills
22
+ const activeStat = await stat(activePath).catch(() => null)
23
+ if (activeStat) {
24
+ installed = true
25
+ const content = await readFile(activePath, 'utf-8').catch(() => '')
26
+ const meta = parseSkillFrontmatter(content)
27
+ installedVersion = meta.version
28
+ } else {
29
+ // Check inactive skills
30
+ const inactiveStat = await stat(inactivePath).catch(() => null)
31
+ if (inactiveStat) {
32
+ installed = true
33
+ const content = await readFile(inactivePath, 'utf-8').catch(() => '')
34
+ const meta = parseSkillFrontmatter(content)
35
+ installedVersion = meta.version
36
+ }
37
+ }
38
+
39
+ return {
40
+ id: item.id,
41
+ name: item.name,
42
+ description: item.description,
43
+ version: item.version,
44
+ author: item.author,
45
+ tags: item.tags || [],
46
+ requiresSecrets: item.requiresSecrets || [],
47
+ files: item.files || [],
48
+ updatedAt: item.updatedAt.toISOString(),
49
+ installed,
50
+ installedVersion,
51
+ hasUpdate: installed && installedVersion ? installedVersion !== item.version : false
52
+ }
53
+ }))
54
+
55
+ return { data: items }
56
+ })