cognova 0.2.13 → 0.2.14

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 (386) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/-mGU8_Hv.js +1 -0
  3. package/.output/public/_nuxt/0GqCtQ9S.js +1 -0
  4. package/.output/public/_nuxt/{DFpmIy6J.js → 1wCoXZ14.js} +1 -1
  5. package/.output/public/_nuxt/2J1KxdHv.js +1 -0
  6. package/.output/public/_nuxt/6VDUZECX.js +1 -0
  7. package/.output/public/_nuxt/{C7m9zGMG.js → 8WMJQbWG.js} +1 -1
  8. package/.output/public/_nuxt/9Rw88G6h.js +1 -0
  9. package/.output/public/_nuxt/{BjsKx597.js → B-yW4SD3.js} +1 -1
  10. package/.output/public/_nuxt/B20jNAhm.js +1 -0
  11. package/.output/public/_nuxt/B3OpTH_e.js +1 -0
  12. package/.output/public/_nuxt/B9Y3_B5G.js +1 -0
  13. package/.output/public/_nuxt/B9_vmatf.js +1 -0
  14. package/.output/public/_nuxt/B9o6sFST.js +1 -0
  15. package/.output/public/_nuxt/{CseYuM6E.js → BAY3_Hrq.js} +1 -1
  16. package/.output/public/_nuxt/{B_9zJTqe.js → BD5rPkc2.js} +3 -3
  17. package/.output/public/_nuxt/BGYoW3kO.js +1 -0
  18. package/.output/public/_nuxt/BHUy5EAj.js +1 -0
  19. package/.output/public/_nuxt/BLdMRpJD.js +1 -0
  20. package/.output/public/_nuxt/{D6tVZcRs.js → BOCn_SGf.js} +12 -12
  21. package/.output/public/_nuxt/BQi8LIrn.js +1 -0
  22. package/.output/public/_nuxt/BS1t375R.js +1 -0
  23. package/.output/public/_nuxt/BTGeP1bA.js +1 -0
  24. package/.output/public/_nuxt/{pdYvpiud.js → BVYYP4eQ.js} +5 -5
  25. package/.output/public/_nuxt/BWQ7zE01.js +1 -0
  26. package/.output/public/_nuxt/BWqJInD3.js +1 -0
  27. package/.output/public/_nuxt/BXdQ9ASJ.js +1 -0
  28. package/.output/public/_nuxt/{DQhm-UPG.js → BXxZokD_.js} +2 -2
  29. package/.output/public/_nuxt/BZ7DAtPi.js +1 -0
  30. package/.output/public/_nuxt/BZm9w7en.js +1 -0
  31. package/.output/public/_nuxt/B_hNqC64.js +1 -0
  32. package/.output/public/_nuxt/Be47YE2L.js +1 -0
  33. package/.output/public/_nuxt/BgIS9_ti.js +39 -0
  34. package/.output/public/_nuxt/BgavRUl_.js +1 -0
  35. package/.output/public/_nuxt/Bh0yGTzr.js +1 -0
  36. package/.output/public/_nuxt/BhhMUror.js +1 -0
  37. package/.output/public/_nuxt/Bj5e7QPz.js +1 -0
  38. package/.output/public/_nuxt/{9kAKMaPC.js → Bnn59-FS.js} +1 -1
  39. package/.output/public/_nuxt/BoCU3mWu.js +1 -0
  40. package/.output/public/_nuxt/Br6epbzY.js +1 -0
  41. package/.output/public/_nuxt/Br81Sr2R.js +1 -0
  42. package/.output/public/_nuxt/BrkEOLHu.js +9 -0
  43. package/.output/public/_nuxt/BtrNCc2S.js +1 -0
  44. package/.output/public/_nuxt/BxsQlbgl.js +1 -0
  45. package/.output/public/_nuxt/BzrhNhdT.js +1 -0
  46. package/.output/public/_nuxt/{B-DMcEU9.js → C-78dDNd.js} +1 -1
  47. package/.output/public/_nuxt/C1oaoi1p.js +1 -0
  48. package/.output/public/_nuxt/C2-_hcwB.js +1 -0
  49. package/.output/public/_nuxt/{TxMdabnL.js → C2Gh3qqr.js} +1 -1
  50. package/.output/public/_nuxt/C2OHaW6l.js +1 -0
  51. package/.output/public/_nuxt/C3szZmvA.js +1 -0
  52. package/.output/public/_nuxt/C3xzleKP.js +1 -0
  53. package/.output/public/_nuxt/C4sG6rdW.js +1 -0
  54. package/.output/public/_nuxt/C5Cu9Fx6.js +1 -0
  55. package/.output/public/_nuxt/{LRO7YHoH.js → C5gfF7J1.js} +1 -1
  56. package/.output/public/_nuxt/C6Eoiclo.js +1 -0
  57. package/.output/public/_nuxt/C7hFztZL.js +1 -0
  58. package/.output/public/_nuxt/CAVUAxNU.js +2 -0
  59. package/.output/public/_nuxt/{CiNxIhaq.js → CCeM5lW2.js} +1 -1
  60. package/.output/public/_nuxt/CDcQ31Eh.js +1 -0
  61. package/.output/public/_nuxt/CHbHVtCy.js +1 -0
  62. package/.output/public/_nuxt/CHnVFnBW.js +1 -0
  63. package/.output/public/_nuxt/CLNcmNQS.js +1 -0
  64. package/.output/public/_nuxt/{D7N3EZ-I.js → CPwCTHun.js} +1 -1
  65. package/.output/public/_nuxt/{CFmvNggn.js → CS8SdmH2.js} +1 -1
  66. package/.output/public/_nuxt/CTGm_mc8.js +1 -0
  67. package/.output/public/_nuxt/{DNcOC5zj.js → CTQFGHjS.js} +1 -1
  68. package/.output/public/_nuxt/{B0nzD8Sk.js → CVVtVzXC.js} +1 -1
  69. package/.output/public/_nuxt/CZNOaqeX.js +1 -0
  70. package/.output/public/_nuxt/C_A_NkeC.js +2 -0
  71. package/.output/public/_nuxt/{CGplHfmR.js → C_doutX-.js} +1 -1
  72. package/.output/public/_nuxt/{BrX-PnSK.js → CbDLhrNA.js} +2 -2
  73. package/.output/public/_nuxt/CePKCqSb.js +1 -0
  74. package/.output/public/_nuxt/Cet4T_yO.js +1 -0
  75. package/.output/public/_nuxt/{C6OSRpRd.js → CjJPkhbc.js} +1 -1
  76. package/.output/public/_nuxt/CkZT4LGq.js +1 -0
  77. package/.output/public/_nuxt/CkrW8sGL.js +1 -0
  78. package/.output/public/_nuxt/Co0UxVsx.js +1 -0
  79. package/.output/public/_nuxt/CqS0zXYQ.js +1 -0
  80. package/.output/public/_nuxt/CskGv_Km.js +1 -0
  81. package/.output/public/_nuxt/{DuzpliIL.js → CuvkTsqs.js} +1 -1
  82. package/.output/public/_nuxt/{B2wI_pYg.js → CxMuZEwX.js} +1 -1
  83. package/.output/public/_nuxt/{9O1MXkck.js → CxSijT71.js} +8 -8
  84. package/.output/public/_nuxt/Cywo6tZI.js +1 -0
  85. package/.output/public/_nuxt/D1reIfpX.js +1 -0
  86. package/.output/public/_nuxt/D1uV2uir.js +1 -0
  87. package/.output/public/_nuxt/{BWuL2CzO.js → D2edadpd.js} +1 -1
  88. package/.output/public/_nuxt/D3cEeQh7.js +1 -0
  89. package/.output/public/_nuxt/D41A2mE2.js +1 -0
  90. package/.output/public/_nuxt/D49P2RhG.js +1 -0
  91. package/.output/public/_nuxt/D867g6Ds.js +1 -0
  92. package/.output/public/_nuxt/DEFWIjWl.js +1 -0
  93. package/.output/public/_nuxt/DFTEBTzZ.js +1 -0
  94. package/.output/public/_nuxt/{-HePz7lp.js → DHRexj9X.js} +2 -2
  95. package/.output/public/_nuxt/DL4EpgqQ.js +1 -0
  96. package/.output/public/_nuxt/DLHnP6tw.js +1 -0
  97. package/.output/public/_nuxt/DM20WaLq.js +1 -0
  98. package/.output/public/_nuxt/{B8DFEjxA.js → DNAMjHbb.js} +1 -1
  99. package/.output/public/_nuxt/{CLkkdThv.js → DP8t9VWs.js} +24 -24
  100. package/.output/public/_nuxt/DTR31rjp.js +1 -0
  101. package/.output/public/_nuxt/{Bc8bTnkd.js → DTlSLSo1.js} +3 -3
  102. package/.output/public/_nuxt/{DowkFZ2V.js → DVdnhfXT.js} +1 -1
  103. package/.output/public/_nuxt/{DvHS7_h2.js → DZikIgHK.js} +1 -1
  104. package/.output/public/_nuxt/D_YGqvw_.js +1 -0
  105. package/.output/public/_nuxt/D_k1YwXm.js +1 -0
  106. package/.output/public/_nuxt/Daf2MbWG.js +7 -0
  107. package/.output/public/_nuxt/DcJ0GstJ.js +1 -0
  108. package/.output/public/_nuxt/DcYKh6QA.js +1 -0
  109. package/.output/public/_nuxt/DhN3_DYH.js +1 -0
  110. package/.output/public/_nuxt/DhSvBSt3.js +1 -0
  111. package/.output/public/_nuxt/DhlIWT8K.js +1 -0
  112. package/.output/public/_nuxt/DjsqyRqt.js +1 -0
  113. package/.output/public/_nuxt/DpSM97eH.js +1 -0
  114. package/.output/public/_nuxt/DqR9SdeU.js +1 -0
  115. package/.output/public/_nuxt/DqmQtg6Y.js +1 -0
  116. package/.output/public/_nuxt/Dsuag_iW.js +1 -0
  117. package/.output/public/_nuxt/Dtr_0IbE.js +1 -0
  118. package/.output/public/_nuxt/DwrmFEZN.js +1 -0
  119. package/.output/public/_nuxt/DxE8r3r4.js +1 -0
  120. package/.output/public/_nuxt/G_CsVlOR.js +1 -0
  121. package/.output/public/_nuxt/Gyw_2f6x.js +1 -0
  122. package/.output/public/_nuxt/HStC1ZyE.js +1 -0
  123. package/.output/public/_nuxt/Hh9mv0Ek.js +1 -0
  124. package/.output/public/_nuxt/LR0kCjbe.js +1 -0
  125. package/.output/public/_nuxt/MYeLvJGV.js +1 -0
  126. package/.output/public/_nuxt/NKs0EGrh.js +1 -0
  127. package/.output/public/_nuxt/PY5EGujn.js +1 -0
  128. package/.output/public/_nuxt/PamJNol9.js +1 -0
  129. package/.output/public/_nuxt/RlvwEbHv.js +1 -0
  130. package/.output/public/_nuxt/{BghuwIGa.js → TNpdJOlc.js} +1 -1
  131. package/.output/public/_nuxt/TSYrPbLR.js +1 -0
  132. package/.output/public/_nuxt/U-eBrbR4.js +1 -0
  133. package/.output/public/_nuxt/UuqXScSw.js +1 -0
  134. package/.output/public/_nuxt/V04-MrLN.js +1 -0
  135. package/.output/public/_nuxt/X0o5GcBb.js +1 -0
  136. package/.output/public/_nuxt/XQNzmQy9.js +1 -0
  137. package/.output/public/_nuxt/Y59XKprr.js +1 -0
  138. package/.output/public/_nuxt/YZQjZgsH.js +1 -0
  139. package/.output/public/_nuxt/_-TGPiLQ.js +1 -0
  140. package/.output/public/_nuxt/builds/latest.json +1 -1
  141. package/.output/public/_nuxt/builds/meta/d7188f50-b42c-4d2c-afab-066d318f0af8.json +1 -0
  142. package/.output/public/_nuxt/dashboard.ByJQ-Wzh.css +1 -0
  143. package/.output/public/_nuxt/entry.ZJxWCrU6.css +1 -0
  144. package/.output/public/_nuxt/{D12qPplu.js → hCeWb_38.js} +1 -1
  145. package/.output/public/_nuxt/{sBzyvWMJ.js → hrPTRWjM.js} +1 -1
  146. package/.output/public/_nuxt/jC4pIK1p.js +1 -0
  147. package/.output/public/_nuxt/jTT1R-Vz.js +1 -0
  148. package/.output/public/_nuxt/{CRRw0Thu.js → kkAMoB43.js} +1 -1
  149. package/.output/public/_nuxt/{h_bXa-f2.js → mzM4BGtv.js} +1 -1
  150. package/.output/public/_nuxt/o-s8JBm2.js +1 -0
  151. package/.output/public/_nuxt/pwJTkIQ4.js +1 -0
  152. package/.output/public/_nuxt/{BL1mkqgd.js → rIgg2Arf.js} +3 -3
  153. package/.output/public/_nuxt/subdxgSQ.js +1 -0
  154. package/.output/public/_nuxt/t8B72leH.js +1 -0
  155. package/.output/public/_nuxt/vCFAHwdt.js +1 -0
  156. package/.output/public/_nuxt/z-MP0bB7.js +1 -0
  157. package/.output/server/chunks/build/CodeIcon-CWD5HcV7.mjs +1 -1
  158. package/.output/server/chunks/build/DropdownMenu-BBrV9nXz.mjs +1 -1
  159. package/.output/server/chunks/build/{EditorToolbar-DIfb5arC.mjs → EditorToolbar-B9OwSI5e.mjs} +3 -3
  160. package/.output/server/chunks/build/{EditorToolbar-DIfb5arC.mjs.map → EditorToolbar-B9OwSI5e.mjs.map} +1 -1
  161. package/.output/server/chunks/build/Img-CWLmvN1t.mjs +1 -1
  162. package/.output/server/chunks/build/MDC-Dx0YPDhe.mjs +1 -1
  163. package/.output/server/chunks/build/Select-BB1oLrCD.mjs +1 -1
  164. package/.output/server/chunks/build/SelectMenu-DPssg6zD.mjs +1 -1
  165. package/.output/server/chunks/build/Table-DCwTlhCj.mjs +1 -1
  166. package/.output/server/chunks/build/Tooltip-TRyl6dje.mjs +1 -1
  167. package/.output/server/chunks/build/Tree-DUhXKd8y.mjs +1 -1
  168. package/.output/server/chunks/build/{_id_-DN00UDdO.mjs → _id_-CwBeklIM.mjs} +296 -430
  169. package/.output/server/chunks/build/_id_-CwBeklIM.mjs.map +1 -0
  170. package/.output/server/chunks/build/{_name_-BnS_KEfX.mjs → _name_-D7MtW4Vu.mjs} +2 -2
  171. package/.output/server/chunks/build/{_name_-BnS_KEfX.mjs.map → _name_-D7MtW4Vu.mjs.map} +1 -1
  172. package/.output/server/chunks/build/{_uuid_-DfJaumTE.mjs → _uuid_-lvG92ein.mjs} +4 -4
  173. package/.output/server/chunks/build/{_uuid_-DfJaumTE.mjs.map → _uuid_-lvG92ein.mjs.map} +1 -1
  174. package/.output/server/chunks/build/account-LDZ4TL6x.mjs +513 -0
  175. package/.output/server/chunks/build/account-LDZ4TL6x.mjs.map +1 -0
  176. package/.output/server/chunks/build/app-CGhRZPNT.mjs +252 -0
  177. package/.output/server/chunks/build/app-CGhRZPNT.mjs.map +1 -0
  178. package/.output/server/chunks/build/{chat-m4-n9vC6.mjs → chat-BphuYhvA.mjs} +18 -27
  179. package/.output/server/chunks/build/chat-BphuYhvA.mjs.map +1 -0
  180. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  181. package/.output/server/chunks/build/cookie-C_iulBi6.mjs +1 -1
  182. package/.output/server/chunks/build/{dashboard-CiVTAZuF.mjs → dashboard-nDujDyOg.mjs} +55 -16
  183. package/.output/server/chunks/build/{dashboard-CiVTAZuF.mjs.map → dashboard-nDujDyOg.mjs.map} +1 -1
  184. package/.output/server/chunks/build/{docs-ChGwOPg5.mjs → docs-Bwucwp0r.mjs} +664 -592
  185. package/.output/server/chunks/build/docs-Bwucwp0r.mjs.map +1 -0
  186. package/.output/server/chunks/build/fetch-BB7Qzkwe.mjs +1 -1
  187. package/.output/server/chunks/build/{hooks-D328DcO6.mjs → hooks-D6PmTth8.mjs} +19 -29
  188. package/.output/server/chunks/build/hooks-D6PmTth8.mjs.map +1 -0
  189. package/.output/server/chunks/build/{index-CAnGTRlu.mjs → index-CJkn2jiM.mjs} +2 -2
  190. package/.output/server/chunks/build/{index-CAnGTRlu.mjs.map → index-CJkn2jiM.mjs.map} +1 -1
  191. package/.output/server/chunks/build/index-CxDxc9fm.mjs +1 -1
  192. package/.output/server/chunks/build/index-Cz9Y6NwN.mjs +723 -0
  193. package/.output/server/chunks/build/index-Cz9Y6NwN.mjs.map +1 -0
  194. package/.output/server/chunks/build/index-hwhuKhuZ.mjs +76 -0
  195. package/.output/server/chunks/build/index-hwhuKhuZ.mjs.map +1 -0
  196. package/.output/server/chunks/build/integrations-D5JWURiJ.mjs +1499 -0
  197. package/.output/server/chunks/build/integrations-D5JWURiJ.mjs.map +1 -0
  198. package/.output/server/chunks/build/{library-Aeg7_Lsb.mjs → library-DxRdgP6X.mjs} +2 -2
  199. package/.output/server/chunks/build/{library-Aeg7_Lsb.mjs.map → library-DxRdgP6X.mjs.map} +1 -1
  200. package/.output/server/chunks/build/{login-DnnElTl2.mjs → login-BmER_VoU.mjs} +2 -2
  201. package/.output/server/chunks/build/{login-DnnElTl2.mjs.map → login-BmER_VoU.mjs.map} +1 -1
  202. package/.output/server/chunks/build/manage-secrets-BWzqc_-f.mjs +669 -0
  203. package/.output/server/chunks/build/manage-secrets-BWzqc_-f.mjs.map +1 -0
  204. package/.output/server/chunks/build/server.mjs +65 -34
  205. package/.output/server/chunks/build/server.mjs.map +1 -1
  206. package/.output/server/chunks/build/settings-neokAVE5.mjs +154 -0
  207. package/.output/server/chunks/build/settings-neokAVE5.mjs.map +1 -0
  208. package/.output/server/chunks/build/styles.mjs +2 -2
  209. package/.output/server/chunks/build/{tasks-DnAFqbtt.mjs → tasks-CnpIQNpS.mjs} +27 -37
  210. package/.output/server/chunks/build/tasks-CnpIQNpS.mjs.map +1 -0
  211. package/.output/server/chunks/build/{useAgents-DHEXiFSc.mjs → useAgents-nmbkB9-_.mjs} +5 -26
  212. package/.output/server/chunks/build/useAgents-nmbkB9-_.mjs.map +1 -0
  213. package/.output/server/chunks/build/{view-n2sYa4Zh.mjs → view-mb0ISqfM.mjs} +3 -3
  214. package/.output/server/chunks/build/{view-n2sYa4Zh.mjs.map → view-mb0ISqfM.mjs.map} +1 -1
  215. package/.output/server/chunks/nitro/nitro.mjs +1000 -858
  216. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  217. package/.output/server/chunks/routes/api/index.get.mjs +17 -2
  218. package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
  219. package/.output/server/chunks/routes/api/index.get3.mjs +21 -3
  220. package/.output/server/chunks/routes/api/index.get3.mjs.map +1 -1
  221. package/.output/server/chunks/routes/api/index.get4.mjs +10 -9
  222. package/.output/server/chunks/routes/api/index.get4.mjs.map +1 -1
  223. package/.output/server/chunks/routes/api/index.get9.mjs +10 -8
  224. package/.output/server/chunks/routes/api/index.get9.mjs.map +1 -1
  225. package/.output/server/chunks/routes/api/memory/search.get.mjs +10 -5
  226. package/.output/server/chunks/routes/api/memory/search.get.mjs.map +1 -1
  227. package/.output/server/chunks/routes/renderer.mjs +1 -1
  228. package/.output/server/index.mjs +1 -1
  229. package/.output/server/package.json +1 -1
  230. package/app/components/AssistantPanel.client.vue +16 -314
  231. package/app/components/agents/AgentCard.vue +111 -0
  232. package/app/components/agents/AgentInfoCard.vue +54 -0
  233. package/app/components/agents/AgentRunHistory.vue +103 -0
  234. package/app/components/agents/AgentRunModal.vue +1 -24
  235. package/app/components/agents/AgentStatsCards.vue +1 -26
  236. package/app/components/assistant/AssistantChat.vue +156 -0
  237. package/app/components/assistant/AssistantTerminal.client.vue +178 -0
  238. package/app/components/chat/ConversationList.vue +2 -12
  239. package/app/components/files/FileTree.vue +23 -202
  240. package/app/components/files/FileTreeModals.vue +226 -0
  241. package/app/components/hooks/HookStatsCards.vue +1 -6
  242. package/app/components/hooks/ToolBreakdownTable.vue +1 -6
  243. package/app/components/search/DashboardSearch.vue +38 -1
  244. package/app/components/tasks/TaskCard.vue +2 -7
  245. package/app/components/tasks/TaskDetail.vue +4 -9
  246. package/app/composables/useSearch.ts +21 -11
  247. package/app/layouts/dashboard.vue +1 -1
  248. package/app/pages/agents/[id].vue +6 -197
  249. package/app/pages/agents/index.vue +9 -142
  250. package/app/pages/settings/account.vue +243 -0
  251. package/app/pages/settings/app.vue +230 -0
  252. package/app/pages/settings/index.vue +12 -0
  253. package/app/pages/settings/integrations.vue +794 -0
  254. package/app/pages/settings/manage-secrets.vue +295 -0
  255. package/app/pages/settings.vue +20 -1581
  256. package/dist/cli/index.js +26 -2
  257. package/package.json +1 -1
  258. package/server/api/agents/index.get.ts +20 -1
  259. package/server/api/conversations/index.get.ts +23 -5
  260. package/server/api/documents/index.get.ts +11 -9
  261. package/server/api/memory/search.get.ts +11 -6
  262. package/server/api/tasks/index.get.ts +11 -9
  263. package/server/drizzle/migrations/0016_full_text_search.sql +127 -0
  264. package/server/drizzle/migrations/meta/_journal.json +7 -0
  265. package/shared/types/index.ts +7 -1
  266. package/shared/utils/formatting.ts +105 -0
  267. package/.output/public/_nuxt/4ALIM-zZ.js +0 -1
  268. package/.output/public/_nuxt/5sUbkh_6.js +0 -16
  269. package/.output/public/_nuxt/6bB8Ev7a.js +0 -1
  270. package/.output/public/_nuxt/7rT1DCe2.js +0 -1
  271. package/.output/public/_nuxt/B2PqR2Vu.js +0 -1
  272. package/.output/public/_nuxt/B5FuOh7E.js +0 -1
  273. package/.output/public/_nuxt/B6om4MW2.js +0 -1
  274. package/.output/public/_nuxt/B7ikW4eF.js +0 -1
  275. package/.output/public/_nuxt/B9kWNcU7.js +0 -1
  276. package/.output/public/_nuxt/BAZ8sewA.js +0 -1
  277. package/.output/public/_nuxt/BCPwL4ma.js +0 -1
  278. package/.output/public/_nuxt/BCrlmHh_.js +0 -1
  279. package/.output/public/_nuxt/BD-AFJWW.js +0 -1
  280. package/.output/public/_nuxt/BGcQMReV.js +0 -1
  281. package/.output/public/_nuxt/BNJJSRKh.js +0 -1
  282. package/.output/public/_nuxt/BNeeERBt.js +0 -1
  283. package/.output/public/_nuxt/BSJb5amZ.js +0 -1
  284. package/.output/public/_nuxt/BSsaE9Db.js +0 -1
  285. package/.output/public/_nuxt/BVO3XpHT.js +0 -1
  286. package/.output/public/_nuxt/B_Lr1vlV.js +0 -1
  287. package/.output/public/_nuxt/Bl0qBhCG.js +0 -1
  288. package/.output/public/_nuxt/Bl43dkDq.js +0 -1
  289. package/.output/public/_nuxt/BnMTFF5R.js +0 -1
  290. package/.output/public/_nuxt/BtV7oNn3.js +0 -1
  291. package/.output/public/_nuxt/BvFYnRMR.js +0 -1
  292. package/.output/public/_nuxt/BvTUBUNN.js +0 -1
  293. package/.output/public/_nuxt/ByLsRRoQ.js +0 -1
  294. package/.output/public/_nuxt/C1LcEMwB.js +0 -1
  295. package/.output/public/_nuxt/C2IiXp9N.js +0 -2
  296. package/.output/public/_nuxt/C796kFT9.js +0 -1
  297. package/.output/public/_nuxt/C8AtdrMH.js +0 -1
  298. package/.output/public/_nuxt/CAWbHTgy.js +0 -1
  299. package/.output/public/_nuxt/CJPrV25_.js +0 -1
  300. package/.output/public/_nuxt/CKKEWapF.js +0 -1
  301. package/.output/public/_nuxt/CNjv28J2.js +0 -1
  302. package/.output/public/_nuxt/CT8s4rqa.js +0 -1
  303. package/.output/public/_nuxt/CZSOrxUy.js +0 -1
  304. package/.output/public/_nuxt/CaNEL9JC.js +0 -39
  305. package/.output/public/_nuxt/CbTLg9oX.js +0 -1
  306. package/.output/public/_nuxt/CfCXpVn5.js +0 -1
  307. package/.output/public/_nuxt/ChmNlvWR.js +0 -1
  308. package/.output/public/_nuxt/Ck0QYdxe.js +0 -1
  309. package/.output/public/_nuxt/Ckb0pu4-.js +0 -1
  310. package/.output/public/_nuxt/CkwPRs1D.js +0 -1
  311. package/.output/public/_nuxt/CmEJg8C6.js +0 -2
  312. package/.output/public/_nuxt/CmL_vMJD.js +0 -1
  313. package/.output/public/_nuxt/Cq8zPxkT.js +0 -1
  314. package/.output/public/_nuxt/CxRnB4NC.js +0 -1
  315. package/.output/public/_nuxt/D0zMyG8n.js +0 -1
  316. package/.output/public/_nuxt/D1XYB283.js +0 -1
  317. package/.output/public/_nuxt/D2NxqyzW.js +0 -1
  318. package/.output/public/_nuxt/D5xyrvFu.js +0 -1
  319. package/.output/public/_nuxt/D8iBB0Py.js +0 -1
  320. package/.output/public/_nuxt/D8oIH8m1.js +0 -1
  321. package/.output/public/_nuxt/DB2zZev7.js +0 -1
  322. package/.output/public/_nuxt/DBrOAqkm.js +0 -1
  323. package/.output/public/_nuxt/DDXDFweK.js +0 -1
  324. package/.output/public/_nuxt/DFZkCmLQ.js +0 -1
  325. package/.output/public/_nuxt/DKZmgHNU.js +0 -1
  326. package/.output/public/_nuxt/DR8tGJhL.js +0 -1
  327. package/.output/public/_nuxt/DVAEVTjy.js +0 -1
  328. package/.output/public/_nuxt/DVqrPkCJ.js +0 -1
  329. package/.output/public/_nuxt/DWZ9ieYa.js +0 -1
  330. package/.output/public/_nuxt/DWj6VsZv.js +0 -1
  331. package/.output/public/_nuxt/DXJ9PxCv.js +0 -1
  332. package/.output/public/_nuxt/D_ziPROx.js +0 -1
  333. package/.output/public/_nuxt/Da2vwoYG.js +0 -1
  334. package/.output/public/_nuxt/Ddz3HcBB.js +0 -1
  335. package/.output/public/_nuxt/DgYei0bK.js +0 -1
  336. package/.output/public/_nuxt/Di_3GV_R.js +0 -1
  337. package/.output/public/_nuxt/Djog1f_e.js +0 -1
  338. package/.output/public/_nuxt/Dkap2-Pj.js +0 -7
  339. package/.output/public/_nuxt/DlJe_sHk.js +0 -1
  340. package/.output/public/_nuxt/DlPOQpH_.js +0 -1
  341. package/.output/public/_nuxt/DmYWMtVA.js +0 -1
  342. package/.output/public/_nuxt/DmxKU7sH.js +0 -1
  343. package/.output/public/_nuxt/DsodHRrQ.js +0 -1
  344. package/.output/public/_nuxt/DwSY6_2U.js +0 -1
  345. package/.output/public/_nuxt/DypJaSm-.js +0 -1
  346. package/.output/public/_nuxt/DzKaXH6P.js +0 -1
  347. package/.output/public/_nuxt/FK-jSuOT.js +0 -1
  348. package/.output/public/_nuxt/Fc2JsQt4.js +0 -1
  349. package/.output/public/_nuxt/IYCBGuRS.js +0 -1
  350. package/.output/public/_nuxt/NrRzUJNY.js +0 -1
  351. package/.output/public/_nuxt/OeVS0Rsb.js +0 -1
  352. package/.output/public/_nuxt/OlF0QnKF.js +0 -1
  353. package/.output/public/_nuxt/QuAoqY7t.js +0 -1
  354. package/.output/public/_nuxt/RlXHkmOd.js +0 -9
  355. package/.output/public/_nuxt/WZnvL9Dh.js +0 -1
  356. package/.output/public/_nuxt/ZvG7a1W3.js +0 -1
  357. package/.output/public/_nuxt/aPNZBVrG.js +0 -1
  358. package/.output/public/_nuxt/builds/meta/495aca73-bfa5-456e-b96a-f02e009c72d3.json +0 -1
  359. package/.output/public/_nuxt/dashboard.BxCOkJwt.css +0 -1
  360. package/.output/public/_nuxt/entry.C_udkZt9.css +0 -1
  361. package/.output/public/_nuxt/evY81hM3.js +0 -1
  362. package/.output/public/_nuxt/i6QBzaEi.js +0 -1
  363. package/.output/public/_nuxt/iTVKJ1kw.js +0 -1
  364. package/.output/public/_nuxt/j92uR3uR.js +0 -1
  365. package/.output/public/_nuxt/jdUkeAj_.js +0 -1
  366. package/.output/public/_nuxt/jeRvcMHU.js +0 -1
  367. package/.output/public/_nuxt/kuv0zpKq.js +0 -1
  368. package/.output/public/_nuxt/l3lKQs7b.js +0 -1
  369. package/.output/public/_nuxt/qIgZ7OXa.js +0 -1
  370. package/.output/public/_nuxt/qcVwZv8e.js +0 -1
  371. package/.output/public/_nuxt/ru8fqqWs.js +0 -1
  372. package/.output/public/_nuxt/sgmhgpCS.js +0 -1
  373. package/.output/public/_nuxt/y2jv0da-.js +0 -1
  374. package/.output/public/_nuxt/yyS4-kAX.js +0 -1
  375. package/.output/public/_nuxt/zIoBLBHF.js +0 -1
  376. package/.output/public/_nuxt/zpazwPgx.js +0 -1
  377. package/.output/server/chunks/build/_id_-DN00UDdO.mjs.map +0 -1
  378. package/.output/server/chunks/build/chat-m4-n9vC6.mjs.map +0 -1
  379. package/.output/server/chunks/build/docs-ChGwOPg5.mjs.map +0 -1
  380. package/.output/server/chunks/build/hooks-D328DcO6.mjs.map +0 -1
  381. package/.output/server/chunks/build/index-C9PuieXh.mjs +0 -820
  382. package/.output/server/chunks/build/index-C9PuieXh.mjs.map +0 -1
  383. package/.output/server/chunks/build/settings-B2KXoGcz.mjs +0 -3232
  384. package/.output/server/chunks/build/settings-B2KXoGcz.mjs.map +0 -1
  385. package/.output/server/chunks/build/tasks-DnAFqbtt.mjs.map +0 -1
  386. package/.output/server/chunks/build/useAgents-DHEXiFSc.mjs.map +0 -1
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { AgentGlobalStats, AgentDetailStats } from '~~/shared/types'
3
+ import { formatCurrency, formatDuration, formatRelativeTime } from '~~/shared/utils/formatting'
3
4
 
4
5
  const props = defineProps<{
5
6
  stats: AgentGlobalStats | AgentDetailStats | null
@@ -7,32 +8,6 @@ const props = defineProps<{
7
8
  loading?: boolean
8
9
  }>()
9
10
 
10
- function formatCurrency(value: number): string {
11
- if (value < 0.01) return '<$0.01'
12
- return `$${value.toFixed(2)}`
13
- }
14
-
15
- function formatDuration(ms: number): string {
16
- if (ms < 1000) return `${ms}ms`
17
- if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`
18
- return `${(ms / 60000).toFixed(1)}m`
19
- }
20
-
21
- function formatRelativeTime(dateStr: string | null): string {
22
- if (!dateStr) return 'Never'
23
- const date = new Date(dateStr)
24
- const now = new Date()
25
- const diff = now.getTime() - date.getTime()
26
- const minutes = Math.floor(diff / 60000)
27
- const hours = Math.floor(diff / 3600000)
28
- const days = Math.floor(diff / 86400000)
29
-
30
- if (minutes < 1) return 'Just now'
31
- if (minutes < 60) return `${minutes}m ago`
32
- if (hours < 24) return `${hours}h ago`
33
- return `${days}d ago`
34
- }
35
-
36
11
  const globalStats = computed(() => {
37
12
  if (props.variant !== 'global' || !props.stats) return []
38
13
  const s = props.stats as AgentGlobalStats
@@ -0,0 +1,156 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ active: boolean
4
+ }>()
5
+
6
+ const {
7
+ assistantLastConversationId
8
+ } = usePreferences()
9
+
10
+ const {
11
+ connectionStatus,
12
+ sessionStatus,
13
+ activeConversationId,
14
+ messages,
15
+ conversations,
16
+ streamingText,
17
+ streamingToolCalls,
18
+ loading,
19
+ connect,
20
+ sendMessage,
21
+ interrupt,
22
+ startNewConversation,
23
+ loadConversation,
24
+ loadConversations
25
+ } = useChat()
26
+
27
+ const messagesContainer = ref<HTMLElement | null>(null)
28
+
29
+ const conversationItems = computed(() =>
30
+ conversations.value.map(c => ({
31
+ label: c.title || `Chat ${new Date(c.startedAt).toLocaleDateString()}`,
32
+ value: c.id
33
+ }))
34
+ )
35
+
36
+ const selectedConversationId = ref<string | undefined>(
37
+ assistantLastConversationId.value ?? undefined
38
+ )
39
+
40
+ // Sync selection to preference cookie, only load if user picked a different conversation
41
+ watch(selectedConversationId, (id) => {
42
+ assistantLastConversationId.value = id ?? null
43
+ if (id && id !== activeConversationId.value)
44
+ loadConversation(id)
45
+ })
46
+
47
+ // Sync when a new conversation is created via chat:session_created
48
+ watch(activeConversationId, (id) => {
49
+ if (id) selectedConversationId.value = id
50
+ })
51
+
52
+ function handleSend(message: string) {
53
+ sendMessage(message)
54
+ nextTick(scrollToBottom)
55
+ }
56
+
57
+ function handleNewChat() {
58
+ startNewConversation()
59
+ selectedConversationId.value = undefined
60
+ }
61
+
62
+ function scrollToBottom() {
63
+ if (messagesContainer.value)
64
+ messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
65
+ }
66
+
67
+ watch(streamingText, () => nextTick(scrollToBottom))
68
+ watch(() => messages.value.length, () => nextTick(scrollToBottom))
69
+
70
+ function setup() {
71
+ connect()
72
+ loadConversations()
73
+ if (assistantLastConversationId.value && !activeConversationId.value)
74
+ loadConversation(assistantLastConversationId.value)
75
+ }
76
+
77
+ watch(() => props.active, (active) => {
78
+ if (active) setup()
79
+ }, { immediate: true })
80
+
81
+ defineExpose({ connectionStatus })
82
+ </script>
83
+
84
+ <template>
85
+ <div class="flex flex-col flex-1 min-h-0">
86
+ <!-- Conversation selector -->
87
+ <div class="flex items-center gap-2 px-3 py-2 border-b border-default">
88
+ <USelectMenu
89
+ v-model="selectedConversationId"
90
+ :items="conversationItems"
91
+ value-key="value"
92
+ placeholder="New conversation"
93
+ size="xs"
94
+ class="flex-1"
95
+ icon="i-lucide-messages-square"
96
+ />
97
+ <UButton
98
+ icon="i-lucide-plus"
99
+ size="xs"
100
+ color="primary"
101
+ variant="soft"
102
+ @click="handleNewChat"
103
+ />
104
+ </div>
105
+
106
+ <!-- Messages -->
107
+ <div
108
+ ref="messagesContainer"
109
+ class="relative flex-1 overflow-y-auto p-3 space-y-3"
110
+ >
111
+ <!-- Loading overlay -->
112
+ <div
113
+ v-if="loading"
114
+ class="absolute inset-0 flex items-center justify-center bg-elevated/80 z-10"
115
+ >
116
+ <UIcon
117
+ name="i-lucide-loader-2"
118
+ class="size-6 animate-spin text-primary"
119
+ />
120
+ </div>
121
+
122
+ <div
123
+ v-if="messages.length === 0 && sessionStatus !== 'streaming' && !loading"
124
+ class="flex flex-col items-center justify-center h-full text-dimmed"
125
+ >
126
+ <UIcon
127
+ name="i-lucide-message-square"
128
+ class="size-8 mb-2"
129
+ />
130
+ <p class="text-sm">
131
+ Send a message to start chatting
132
+ </p>
133
+ </div>
134
+
135
+ <ChatMessageBubble
136
+ v-for="msg in messages"
137
+ :key="msg.id"
138
+ :message="msg"
139
+ />
140
+
141
+ <ChatStreamingMessage
142
+ v-if="sessionStatus === 'streaming'"
143
+ :text="streamingText"
144
+ :tool-calls="streamingToolCalls"
145
+ />
146
+ </div>
147
+
148
+ <!-- Input -->
149
+ <ChatInput
150
+ :session-status="sessionStatus"
151
+ :connection-status="connectionStatus"
152
+ @send="handleSend"
153
+ @interrupt="interrupt"
154
+ />
155
+ </div>
156
+ </template>
@@ -0,0 +1,178 @@
1
+ <script setup lang="ts">
2
+ import { Terminal } from '@xterm/xterm'
3
+ import { FitAddon } from '@xterm/addon-fit'
4
+ import { WebLinksAddon } from '@xterm/addon-web-links'
5
+ import '@xterm/xterm/css/xterm.css'
6
+
7
+ const props = defineProps<{
8
+ active: boolean
9
+ }>()
10
+
11
+ const terminalRef = ref<HTMLDivElement | null>(null)
12
+ const terminal = ref<Terminal | null>(null)
13
+ const fitAddon = ref<FitAddon | null>(null)
14
+ const terminalInitialized = ref(false)
15
+
16
+ const {
17
+ status,
18
+ connect,
19
+ disconnect,
20
+ sendInput,
21
+ sendResize,
22
+ startPingInterval,
23
+ stopPingInterval
24
+ } = useTerminal()
25
+
26
+ const statusIcon = computed(() => {
27
+ switch (status.value) {
28
+ case 'connected': return 'i-lucide-wifi'
29
+ case 'connecting': return 'i-lucide-loader-2'
30
+ default: return 'i-lucide-wifi-off'
31
+ }
32
+ })
33
+
34
+ function statusClasses(s: string) {
35
+ return [
36
+ s === 'connecting' && 'animate-spin',
37
+ s === 'connected' && 'text-success',
38
+ (s === 'error' || s === 'disconnected') && 'text-muted'
39
+ ]
40
+ }
41
+
42
+ function initTerminal() {
43
+ if (!terminalRef.value || terminalInitialized.value) return
44
+
45
+ const term = new Terminal({
46
+ cursorBlink: true,
47
+ fontSize: 14,
48
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
49
+ theme: {
50
+ background: '#1a1a1a',
51
+ foreground: '#e5e5e5',
52
+ cursor: '#e5e5e5',
53
+ cursorAccent: '#1a1a1a',
54
+ selectionBackground: '#3b3b3b',
55
+ black: '#1a1a1a',
56
+ red: '#ff5555',
57
+ green: '#50fa7b',
58
+ yellow: '#f1fa8c',
59
+ blue: '#6272a4',
60
+ magenta: '#ff79c6',
61
+ cyan: '#8be9fd',
62
+ white: '#e5e5e5',
63
+ brightBlack: '#4d4d4d',
64
+ brightRed: '#ff6e6e',
65
+ brightGreen: '#69ff94',
66
+ brightYellow: '#ffffa5',
67
+ brightBlue: '#d6acff',
68
+ brightMagenta: '#ff92df',
69
+ brightCyan: '#a4ffff',
70
+ brightWhite: '#ffffff'
71
+ }
72
+ })
73
+
74
+ const fit = new FitAddon()
75
+ fitAddon.value = fit
76
+
77
+ term.loadAddon(fit)
78
+ term.loadAddon(new WebLinksAddon())
79
+
80
+ term.open(terminalRef.value)
81
+ fit.fit()
82
+
83
+ terminal.value = term
84
+ terminalInitialized.value = true
85
+
86
+ term.onData((data) => {
87
+ sendInput(data)
88
+ })
89
+ term.onResize(({ cols, rows }) => {
90
+ sendResize(cols, rows)
91
+ })
92
+
93
+ connect(term)
94
+ startPingInterval()
95
+ }
96
+
97
+ function handleResize() {
98
+ if (fitAddon.value && terminal.value)
99
+ fitAddon.value.fit()
100
+ }
101
+
102
+ function handleReconnect() {
103
+ if (status.value === 'connecting') return
104
+ if (!terminalInitialized.value) {
105
+ nextTick(initTerminal)
106
+ return
107
+ }
108
+ if (terminal.value)
109
+ connect(terminal.value)
110
+ }
111
+
112
+ let resizeObserver: ResizeObserver | null = null
113
+
114
+ function setup() {
115
+ if (!terminalInitialized.value) {
116
+ initTerminal()
117
+ if (terminalRef.value) {
118
+ resizeObserver = new ResizeObserver(() => handleResize())
119
+ resizeObserver.observe(terminalRef.value)
120
+ }
121
+ } else {
122
+ handleResize()
123
+ terminal.value?.focus()
124
+ }
125
+ }
126
+
127
+ watch(() => props.active, (active) => {
128
+ if (active) nextTick(setup)
129
+ }, { immediate: true })
130
+
131
+ onUnmounted(() => {
132
+ stopPingInterval()
133
+ disconnect()
134
+ if (resizeObserver) resizeObserver.disconnect()
135
+ if (terminal.value) terminal.value.dispose()
136
+ })
137
+
138
+ defineExpose({ status })
139
+ </script>
140
+
141
+ <template>
142
+ <div class="flex flex-col flex-1 min-h-0">
143
+ <div class="flex items-center justify-between px-3 py-1.5 border-b border-default text-sm bg-muted/50">
144
+ <div class="flex items-center gap-2 text-muted text-xs">
145
+ <UIcon
146
+ :name="statusIcon"
147
+ :class="['size-3.5', ...statusClasses(status)]"
148
+ />
149
+ <span>{{ status === 'connected' ? 'Connected' : status === 'connecting' ? 'Connecting...' : status === 'error' ? 'Connection error' : 'Disconnected' }}</span>
150
+ </div>
151
+ <UButton
152
+ v-if="status === 'disconnected' || status === 'error'"
153
+ size="xs"
154
+ color="neutral"
155
+ variant="ghost"
156
+ icon="i-lucide-refresh-cw"
157
+ @click="handleReconnect"
158
+ >
159
+ Reconnect
160
+ </UButton>
161
+ </div>
162
+
163
+ <div
164
+ ref="terminalRef"
165
+ class="flex-1 p-1 bg-[#1a1a1a]"
166
+ />
167
+ </div>
168
+ </template>
169
+
170
+ <style>
171
+ .xterm {
172
+ height: 100%;
173
+ }
174
+
175
+ .xterm-viewport {
176
+ overflow-y: auto !important;
177
+ }
178
+ </style>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { ChatConversation } from '~~/shared/types'
3
+ import { formatRelativeTime } from '~~/shared/utils/formatting'
3
4
 
4
5
  defineProps<{
5
6
  conversations: ChatConversation[]
@@ -11,17 +12,6 @@ const emit = defineEmits<{
11
12
  delete: [id: string]
12
13
  new: []
13
14
  }>()
14
-
15
- function formatDate(date: Date | string) {
16
- const d = new Date(date)
17
- const now = new Date()
18
- const diff = now.getTime() - d.getTime()
19
-
20
- if (diff < 60000) return 'just now'
21
- if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`
22
- if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`
23
- return d.toLocaleDateString()
24
- }
25
15
  </script>
26
16
 
27
17
  <template>
@@ -74,7 +64,7 @@ function formatDate(date: Date | string) {
74
64
  />
75
65
  </div>
76
66
  <div class="flex items-center gap-2 mt-1 text-xs text-dimmed">
77
- <span>{{ formatDate(conv.startedAt) }}</span>
67
+ <span>{{ formatRelativeTime(conv.startedAt) }}</span>
78
68
  <span v-if="conv.messageCount">{{ conv.messageCount }} msgs</span>
79
69
  <span v-if="conv.totalCostUsd > 0">${{ conv.totalCostUsd.toFixed(4) }}</span>
80
70
  </div>
@@ -68,40 +68,29 @@ const showNewFileModal = ref(false)
68
68
  const showNewFolderModal = ref(false)
69
69
  const showRenameModal = ref(false)
70
70
  const showDeleteConfirm = ref(false)
71
- const newItemName = ref('')
72
71
 
73
72
  const contextMenuItems = computed(() => [
74
73
  [{
75
74
  label: 'New File',
76
75
  icon: 'i-lucide-file-plus',
77
- onSelect: () => {
78
- newItemName.value = ''
79
- showNewFileModal.value = true
80
- }
76
+ onSelect: () => { showNewFileModal.value = true }
81
77
  }, {
82
78
  label: 'New Folder',
83
79
  icon: 'i-lucide-folder-plus',
84
- onSelect: () => {
85
- newItemName.value = ''
86
- showNewFolderModal.value = true
87
- }
80
+ onSelect: () => { showNewFolderModal.value = true }
88
81
  }],
89
82
  [{
90
83
  label: 'Rename',
91
84
  icon: 'i-lucide-pencil',
92
85
  onSelect: () => {
93
- if (contextMenuTarget.value) {
94
- newItemName.value = contextMenuTarget.value.label
86
+ if (contextMenuTarget.value)
95
87
  showRenameModal.value = true
96
- }
97
88
  }
98
89
  }, {
99
90
  label: 'Delete',
100
91
  icon: 'i-lucide-trash-2',
101
92
  color: 'error' as const,
102
- onSelect: () => {
103
- showDeleteConfirm.value = true
104
- }
93
+ onSelect: () => { showDeleteConfirm.value = true }
105
94
  }]
106
95
  ])
107
96
 
@@ -112,18 +101,14 @@ function handleSelect(item: TreeItem) {
112
101
  }
113
102
  }
114
103
 
115
- async function handleCreateFile() {
116
- if (!newItemName.value.trim()) return
117
-
104
+ async function handleCreateFile(name: string) {
118
105
  const parentPath = contextMenuTarget.value?.type === 'directory'
119
106
  ? contextMenuTarget.value.path
120
107
  : '/'
121
108
 
122
- // Add .md extension if not present
123
- let filename = newItemName.value.trim()
124
- if (!filename.includes('.')) {
109
+ let filename = name
110
+ if (!filename.includes('.'))
125
111
  filename += '.md'
126
- }
127
112
 
128
113
  try {
129
114
  const path = await createFile(parentPath, filename)
@@ -132,39 +117,28 @@ async function handleCreateFile() {
132
117
  } catch {
133
118
  // Error handled in composable
134
119
  }
135
-
136
- showNewFileModal.value = false
137
- newItemName.value = ''
138
120
  }
139
121
 
140
- async function handleCreateFolder() {
141
- if (!newItemName.value.trim()) return
142
-
122
+ async function handleCreateFolder(name: string) {
143
123
  const parentPath = contextMenuTarget.value?.type === 'directory'
144
124
  ? contextMenuTarget.value.path
145
125
  : '/'
146
126
 
147
127
  try {
148
- await createFolder(parentPath, newItemName.value.trim())
128
+ await createFolder(parentPath, name)
149
129
  } catch {
150
130
  // Error handled in composable
151
131
  }
152
-
153
- showNewFolderModal.value = false
154
- newItemName.value = ''
155
132
  }
156
133
 
157
- async function handleRename() {
158
- if (!contextMenuTarget.value || !newItemName.value.trim()) return
134
+ async function handleRename(name: string) {
135
+ if (!contextMenuTarget.value) return
159
136
 
160
137
  try {
161
- await renameItem(contextMenuTarget.value.path, newItemName.value.trim())
138
+ await renameItem(contextMenuTarget.value.path, name)
162
139
  } catch {
163
140
  // Error handled in composable
164
141
  }
165
-
166
- showRenameModal.value = false
167
- newItemName.value = ''
168
142
  }
169
143
 
170
144
  async function handleDelete() {
@@ -175,8 +149,6 @@ async function handleDelete() {
175
149
  } catch {
176
150
  // Error handled in composable
177
151
  }
178
-
179
- showDeleteConfirm.value = false
180
152
  }
181
153
 
182
154
  onMounted(() => {
@@ -270,167 +242,16 @@ onMounted(() => {
270
242
  </UTree>
271
243
  </UContextMenu>
272
244
 
273
- <!-- New File Modal -->
274
- <UModal v-model:open="showNewFileModal">
275
- <template #content>
276
- <UCard>
277
- <template #header>
278
- <div class="flex items-center gap-2">
279
- <UIcon
280
- name="i-lucide-file-plus"
281
- class="size-5"
282
- />
283
- <span class="font-semibold">New File</span>
284
- </div>
285
- </template>
286
-
287
- <UInput
288
- v-model="newItemName"
289
- placeholder="filename.md"
290
- autofocus
291
- @keyup.enter="handleCreateFile"
292
- />
293
-
294
- <template #footer>
295
- <div class="flex justify-end gap-2">
296
- <UButton
297
- color="neutral"
298
- variant="ghost"
299
- @click="showNewFileModal = false"
300
- >
301
- Cancel
302
- </UButton>
303
- <UButton @click="handleCreateFile">
304
- Create
305
- </UButton>
306
- </div>
307
- </template>
308
- </UCard>
309
- </template>
310
- </UModal>
311
-
312
- <!-- New Folder Modal -->
313
- <UModal v-model:open="showNewFolderModal">
314
- <template #content>
315
- <UCard>
316
- <template #header>
317
- <div class="flex items-center gap-2">
318
- <UIcon
319
- name="i-lucide-folder-plus"
320
- class="size-5"
321
- />
322
- <span class="font-semibold">New Folder</span>
323
- </div>
324
- </template>
325
-
326
- <UInput
327
- v-model="newItemName"
328
- placeholder="folder-name"
329
- autofocus
330
- @keyup.enter="handleCreateFolder"
331
- />
332
-
333
- <template #footer>
334
- <div class="flex justify-end gap-2">
335
- <UButton
336
- color="neutral"
337
- variant="ghost"
338
- @click="showNewFolderModal = false"
339
- >
340
- Cancel
341
- </UButton>
342
- <UButton @click="handleCreateFolder">
343
- Create
344
- </UButton>
345
- </div>
346
- </template>
347
- </UCard>
348
- </template>
349
- </UModal>
350
-
351
- <!-- Rename Modal -->
352
- <UModal v-model:open="showRenameModal">
353
- <template #content>
354
- <UCard>
355
- <template #header>
356
- <div class="flex items-center gap-2">
357
- <UIcon
358
- name="i-lucide-pencil"
359
- class="size-5"
360
- />
361
- <span class="font-semibold">Rename</span>
362
- </div>
363
- </template>
364
-
365
- <UInput
366
- v-model="newItemName"
367
- placeholder="new-name"
368
- autofocus
369
- @keyup.enter="handleRename"
370
- />
371
-
372
- <template #footer>
373
- <div class="flex justify-end gap-2">
374
- <UButton
375
- color="neutral"
376
- variant="ghost"
377
- @click="showRenameModal = false"
378
- >
379
- Cancel
380
- </UButton>
381
- <UButton @click="handleRename">
382
- Rename
383
- </UButton>
384
- </div>
385
- </template>
386
- </UCard>
387
- </template>
388
- </UModal>
389
-
390
- <!-- Delete Confirmation -->
391
- <UModal v-model:open="showDeleteConfirm">
392
- <template #content>
393
- <UCard>
394
- <template #header>
395
- <div class="flex items-center gap-2 text-error">
396
- <UIcon
397
- name="i-lucide-trash-2"
398
- class="size-5"
399
- />
400
- <span class="font-semibold">Delete</span>
401
- </div>
402
- </template>
403
-
404
- <p>
405
- Are you sure you want to delete
406
- <strong>{{ contextMenuTarget?.label }}</strong>?
407
- </p>
408
- <p
409
- v-if="contextMenuTarget?.type === 'directory'"
410
- class="text-sm text-dimmed mt-1"
411
- >
412
- This will delete all files and folders inside.
413
- </p>
414
-
415
- <template #footer>
416
- <div class="flex justify-end gap-2">
417
- <UButton
418
- color="neutral"
419
- variant="ghost"
420
- @click="showDeleteConfirm = false"
421
- >
422
- Cancel
423
- </UButton>
424
- <UButton
425
- color="error"
426
- @click="handleDelete"
427
- >
428
- Delete
429
- </UButton>
430
- </div>
431
- </template>
432
- </UCard>
433
- </template>
434
- </UModal>
245
+ <FilesFileTreeModals
246
+ v-model:show-new-file="showNewFileModal"
247
+ v-model:show-new-folder="showNewFolderModal"
248
+ v-model:show-rename="showRenameModal"
249
+ v-model:show-delete="showDeleteConfirm"
250
+ :context-target="contextMenuTarget"
251
+ @create-file="handleCreateFile"
252
+ @create-folder="handleCreateFolder"
253
+ @rename="handleRename"
254
+ @delete="handleDelete"
255
+ />
435
256
  </div>
436
257
  </template>