@geminilight/mindos 0.6.52 → 0.6.54

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 (529) hide show
  1. package/README.md +27 -5
  2. package/README_zh.md +27 -5
  3. package/_standalone/.mindos-build-version +1 -1
  4. package/_standalone/.next/BUILD_ID +1 -1
  5. package/_standalone/.next/app-path-routes-manifest.json +17 -14
  6. package/_standalone/.next/build-manifest.json +3 -3
  7. package/_standalone/.next/cache/.previewinfo +1 -1
  8. package/_standalone/.next/cache/.rscinfo +1 -1
  9. package/_standalone/.next/cache/config.json +3 -3
  10. package/_standalone/.next/prerender-manifest.json +3 -3
  11. package/_standalone/.next/react-loadable-manifest.json +18 -2
  12. package/_standalone/.next/routes-manifest.json +18 -0
  13. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  14. package/_standalone/.next/server/app/_global-error/page.js +1 -1
  15. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  16. package/_standalone/.next/server/app/_global-error.html +2 -2
  17. package/_standalone/.next/server/app/_global-error.rsc +2 -2
  18. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  19. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  21. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  22. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  23. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  24. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  25. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  26. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  27. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  28. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  29. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/agents/page.js +3 -3
  31. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  32. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  35. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  41. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  42. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  43. package/_standalone/.next/server/app/api/ask/route.js +44 -16
  44. package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
  45. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  46. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  47. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  48. package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
  49. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  50. package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
  51. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
  53. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  54. package/_standalone/.next/server/app/api/export/route.js +2 -2
  55. package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
  56. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  58. package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
  59. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  60. package/_standalone/.next/server/app/api/file/raw/route.js +1 -0
  61. package/_standalone/.next/server/app/api/file/raw/route.js.nft.json +1 -0
  62. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -0
  63. package/_standalone/.next/server/app/api/file/route.js +1 -1
  64. package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
  65. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  66. package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  67. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  68. package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  69. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  70. package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
  71. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  72. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  73. package/_standalone/.next/server/app/api/inbox/route.js +1 -1
  74. package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
  75. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  76. package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
  77. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  78. package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
  79. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  80. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  81. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  82. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  83. package/_standalone/.next/server/app/api/mcp/status/route.js +1 -1
  84. package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
  85. package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
  86. package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
  87. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  88. package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
  89. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/restart/route.js +1 -1
  91. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  92. package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  93. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  94. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  96. package/_standalone/.next/server/app/api/settings/route.js +1 -1
  97. package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  98. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  99. package/_standalone/.next/server/app/api/settings/test-key/route.js +1 -1
  100. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  102. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  103. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  104. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  105. package/_standalone/.next/server/app/api/setup/route.js +1 -1
  106. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  107. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  108. package/_standalone/.next/server/app/api/sync/route.js +1 -1
  109. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  110. package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
  111. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  112. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  113. package/_standalone/.next/server/app/api/update/route.js +1 -1
  114. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  115. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  116. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  117. package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
  118. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  119. package/_standalone/.next/server/app/changes/page.js +2 -2
  120. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  121. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  122. package/_standalone/.next/server/app/echo/[segment]/page.js +3 -3
  123. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  124. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  125. package/_standalone/.next/server/app/echo/page.js +1 -1
  126. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  127. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  128. package/_standalone/.next/server/app/explore/page.js +2 -2
  129. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  130. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  131. package/_standalone/.next/server/app/help/page.js +2 -2
  132. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  133. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  134. package/_standalone/.next/server/app/inbox/history/page.js +2 -0
  135. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -0
  136. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -0
  137. package/_standalone/.next/server/app/login/page.js +2 -2
  138. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  139. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  140. package/_standalone/.next/server/app/page.js +3 -3
  141. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  142. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  143. package/_standalone/.next/server/app/setup/page.js +2 -2
  144. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  145. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  146. package/_standalone/.next/server/app/trash/page.js +3 -3
  147. package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
  148. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  149. package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
  150. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  151. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  152. package/_standalone/.next/server/app/wiki/page.js +2 -0
  153. package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -0
  154. package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -0
  155. package/_standalone/.next/server/app-paths-manifest.json +17 -14
  156. package/_standalone/.next/server/chunks/2190.js +2 -2
  157. package/_standalone/.next/server/chunks/2364.js +2 -0
  158. package/_standalone/.next/server/chunks/357.js +1 -0
  159. package/_standalone/.next/server/chunks/530.js +219 -0
  160. package/_standalone/.next/server/chunks/6054.js +52 -0
  161. package/_standalone/.next/server/chunks/6539.js +1 -1
  162. package/_standalone/.next/server/chunks/8388.js +2 -2
  163. package/_standalone/.next/server/chunks/953.js +4 -4
  164. package/_standalone/.next/server/middleware-build-manifest.js +1 -1
  165. package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  166. package/_standalone/.next/server/next-font-manifest.js +1 -1
  167. package/_standalone/.next/server/next-font-manifest.json +1 -1
  168. package/_standalone/.next/server/pages/500.html +2 -2
  169. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  170. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  171. package/_standalone/.next/static/2hrwFOLEOZhHQHfrIt-Dw/_buildManifest.js +1 -0
  172. package/_standalone/.next/static/chunks/1053-2874859f7caefa0f.js +29 -0
  173. package/_standalone/.next/static/chunks/178-105779afb62d36d9.js +1 -0
  174. package/_standalone/.next/static/chunks/1814.b08e9fb85dd3b13c.js +1 -0
  175. package/_standalone/.next/static/chunks/{1880-3ec02adc80531825.js → 1880-7abf971bcfd2389b.js} +2 -2
  176. package/_standalone/.next/static/chunks/{3160-83a7e0b94414b3ac.js → 2218-d54538000574ffef.js} +1 -1
  177. package/_standalone/.next/static/chunks/254-32719a9bea2e74f0.js +1 -0
  178. package/_standalone/.next/static/chunks/362.a77be2f206db7b19.js +1 -0
  179. package/_standalone/.next/static/chunks/4237-ffc6e7c15d4007b6.js +1 -0
  180. package/_standalone/.next/static/chunks/7035-2af69391c7b1ad95.js +1 -0
  181. package/_standalone/.next/static/chunks/7322-d67d05067544864c.js +1 -0
  182. package/_standalone/.next/static/chunks/{6926-4af497b83952fa87.js → 8409-de5726a4a278d28f.js} +1 -1
  183. package/_standalone/.next/static/chunks/8753-ea9db680b0f70f25.js +1 -0
  184. package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/{route-b07a5983e85bc5e3.js → route-e240db6d5049d336.js} +1 -1
  185. package/_standalone/.next/static/chunks/app/_global-error/{page-b07a5983e85bc5e3.js → page-e240db6d5049d336.js} +1 -1
  186. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-f006a70f6889eb56.js +1 -0
  187. package/_standalone/.next/static/chunks/app/agents/page-bd522e428e3acb78.js +5 -0
  188. package/_standalone/.next/static/chunks/app/api/a2a/agents/{route-b07a5983e85bc5e3.js → route-e240db6d5049d336.js} +1 -1
  189. package/_standalone/.next/static/chunks/app/api/a2a/delegations/{route-b07a5983e85bc5e3.js → route-e240db6d5049d336.js} +1 -1
  190. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-e240db6d5049d336.js +1 -0
  191. package/_standalone/.next/static/chunks/app/api/a2a/route-e240db6d5049d336.js +1 -0
  192. package/_standalone/.next/static/chunks/app/api/acp/config/route-e240db6d5049d336.js +1 -0
  193. package/_standalone/.next/static/chunks/app/api/acp/detect/route-e240db6d5049d336.js +1 -0
  194. package/_standalone/.next/static/chunks/app/api/acp/install/route-e240db6d5049d336.js +1 -0
  195. package/_standalone/.next/static/chunks/app/api/acp/registry/route-e240db6d5049d336.js +1 -0
  196. package/_standalone/.next/static/chunks/app/api/acp/session/route-e240db6d5049d336.js +1 -0
  197. package/_standalone/.next/static/chunks/app/api/agent-activity/route-e240db6d5049d336.js +1 -0
  198. package/_standalone/.next/static/chunks/app/api/ask/route-e240db6d5049d336.js +1 -0
  199. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-e240db6d5049d336.js +1 -0
  200. package/_standalone/.next/static/chunks/app/api/auth/route-e240db6d5049d336.js +1 -0
  201. package/_standalone/.next/static/chunks/app/api/backlinks/route-e240db6d5049d336.js +1 -0
  202. package/_standalone/.next/static/chunks/app/api/bootstrap/route-e240db6d5049d336.js +1 -0
  203. package/_standalone/.next/static/chunks/app/api/changes/route-e240db6d5049d336.js +1 -0
  204. package/_standalone/.next/static/chunks/app/api/export/route-e240db6d5049d336.js +1 -0
  205. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-e240db6d5049d336.js +1 -0
  206. package/_standalone/.next/static/chunks/app/api/file/import/route-e240db6d5049d336.js +1 -0
  207. package/_standalone/.next/static/chunks/app/api/file/raw/route-e240db6d5049d336.js +1 -0
  208. package/_standalone/.next/static/chunks/app/api/file/route-e240db6d5049d336.js +1 -0
  209. package/_standalone/.next/static/chunks/app/api/files/route-e240db6d5049d336.js +1 -0
  210. package/_standalone/.next/static/chunks/app/api/git/route-e240db6d5049d336.js +1 -0
  211. package/_standalone/.next/static/chunks/app/api/graph/route-e240db6d5049d336.js +1 -0
  212. package/_standalone/.next/static/chunks/app/api/health/route-e240db6d5049d336.js +1 -0
  213. package/_standalone/.next/static/chunks/app/api/inbox/route-e240db6d5049d336.js +1 -0
  214. package/_standalone/.next/static/chunks/app/api/init/route-e240db6d5049d336.js +1 -0
  215. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-e240db6d5049d336.js +1 -0
  216. package/_standalone/.next/static/chunks/app/api/mcp/install/route-e240db6d5049d336.js +1 -0
  217. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-e240db6d5049d336.js +1 -0
  218. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-e240db6d5049d336.js +1 -0
  219. package/_standalone/.next/static/chunks/app/api/mcp/status/route-e240db6d5049d336.js +1 -0
  220. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-e240db6d5049d336.js +1 -0
  221. package/_standalone/.next/static/chunks/app/api/monitoring/route-e240db6d5049d336.js +1 -0
  222. package/_standalone/.next/static/chunks/app/api/recent-files/route-e240db6d5049d336.js +1 -0
  223. package/_standalone/.next/static/chunks/app/api/restart/route-e240db6d5049d336.js +1 -0
  224. package/_standalone/.next/static/chunks/app/api/search/route-e240db6d5049d336.js +1 -0
  225. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-e240db6d5049d336.js +1 -0
  226. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-e240db6d5049d336.js +1 -0
  227. package/_standalone/.next/static/chunks/app/api/settings/route-e240db6d5049d336.js +1 -0
  228. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-e240db6d5049d336.js +1 -0
  229. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-e240db6d5049d336.js +1 -0
  230. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-e240db6d5049d336.js +1 -0
  231. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-e240db6d5049d336.js +1 -0
  232. package/_standalone/.next/static/chunks/app/api/setup/ls/route-e240db6d5049d336.js +1 -0
  233. package/_standalone/.next/static/chunks/app/api/setup/route-e240db6d5049d336.js +1 -0
  234. package/_standalone/.next/static/chunks/app/api/skills/route-e240db6d5049d336.js +1 -0
  235. package/_standalone/.next/static/chunks/app/api/sync/route-e240db6d5049d336.js +1 -0
  236. package/_standalone/.next/static/chunks/app/api/tree-version/route-e240db6d5049d336.js +1 -0
  237. package/_standalone/.next/static/chunks/app/api/uninstall/route-e240db6d5049d336.js +1 -0
  238. package/_standalone/.next/static/chunks/app/api/update/route-e240db6d5049d336.js +1 -0
  239. package/_standalone/.next/static/chunks/app/api/update-check/route-e240db6d5049d336.js +1 -0
  240. package/_standalone/.next/static/chunks/app/api/update-status/route-e240db6d5049d336.js +1 -0
  241. package/_standalone/.next/static/chunks/app/api/workflows/route-e240db6d5049d336.js +1 -0
  242. package/_standalone/.next/static/chunks/app/changes/page-5a72144d1080a699.js +1 -0
  243. package/_standalone/.next/static/chunks/app/echo/[segment]/{page-88df174dd64b2c76.js → page-6710da1f581b2854.js} +2 -2
  244. package/_standalone/.next/static/chunks/app/echo/page-e240db6d5049d336.js +1 -0
  245. package/_standalone/.next/static/chunks/app/explore/{page-5eb2835e9e3ab4bb.js → page-d3d99308146c2240.js} +1 -1
  246. package/_standalone/.next/static/chunks/app/global-error-c37d50db6128ec01.js +1 -0
  247. package/_standalone/.next/static/chunks/app/help/page-222df603080b5fab.js +1 -0
  248. package/_standalone/.next/static/chunks/app/inbox/history/page-07819cf95cb0805f.js +1 -0
  249. package/_standalone/.next/static/chunks/app/layout-8eacff5813458190.js +186 -0
  250. package/_standalone/.next/static/chunks/app/loading-e240db6d5049d336.js +1 -0
  251. package/_standalone/.next/static/chunks/app/login/{page-24236460fa7c11d0.js → page-0eeef685052869a6.js} +1 -1
  252. package/_standalone/.next/static/chunks/app/page-5a6c9455efe8a0df.js +7 -0
  253. package/_standalone/.next/static/chunks/app/setup/{page-99f40e9337388cda.js → page-9a81fa4d82c6351b.js} +1 -1
  254. package/_standalone/.next/static/chunks/app/trash/page-72d0ae3649ac4b6c.js +1 -0
  255. package/_standalone/.next/static/chunks/app/view/[...path]/loading-e240db6d5049d336.js +1 -0
  256. package/_standalone/.next/static/chunks/app/view/[...path]/not-found-fc04c2bd4f35bc6f.js +1 -0
  257. package/_standalone/.next/static/chunks/app/view/[...path]/page-e8699f96589c0979.js +12 -0
  258. package/_standalone/.next/static/chunks/app/wiki/page-d492256a93f0b8bc.js +1 -0
  259. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-e240db6d5049d336.js +1 -0
  260. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-e240db6d5049d336.js +1 -0
  261. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-e240db6d5049d336.js +1 -0
  262. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-e240db6d5049d336.js +1 -0
  263. package/_standalone/.next/static/chunks/{webpack-bbd44cbc83dc0aa4.js → webpack-73c9da80c6c1ebfe.js} +1 -1
  264. package/_standalone/.next/static/css/66f8a81e4eda06d4.css +1 -0
  265. package/_standalone/.next/static/css/a4a2b71142b311af.css +31 -0
  266. package/_standalone/.next/trace +64 -64
  267. package/_standalone/.next/types/routes.d.ts +5 -2
  268. package/_standalone/.next/types/validator.ts +27 -0
  269. package/_standalone/__tests__/agents/agents-content-dashboard.test.tsx +1 -0
  270. package/_standalone/__tests__/agents/agents-content-model.test.ts +13 -0
  271. package/_standalone/__tests__/core/inbox.test.ts +168 -0
  272. package/_standalone/__tests__/core/sync.test.ts +37 -0
  273. package/_standalone/__tests__/panels/agents-panel-hub.test.tsx +1 -0
  274. package/_standalone/app/globals.css +29 -3
  275. package/_standalone/components/ActivityBar.tsx +9 -9
  276. package/_standalone/components/AskFab.tsx +1 -1
  277. package/_standalone/components/Backlinks.tsx +1 -1
  278. package/_standalone/components/Breadcrumb.tsx +1 -1
  279. package/_standalone/components/CreateSpaceModal.tsx +1 -1
  280. package/_standalone/components/EchoSpotlight.tsx +14 -10
  281. package/_standalone/components/Editor.tsx +1 -1
  282. package/_standalone/components/ExportModal.tsx +3 -3
  283. package/_standalone/components/FileTree.tsx +6 -11
  284. package/_standalone/components/GuideCard.tsx +1 -1
  285. package/_standalone/components/ImportModal.tsx +1 -2
  286. package/_standalone/components/KeyboardShortcuts.tsx +1 -1
  287. package/_standalone/components/MarkdownEditor.tsx +1 -1
  288. package/_standalone/components/OnboardingView.tsx +2 -2
  289. package/_standalone/components/OrganizeToast.tsx +3 -1
  290. package/_standalone/components/Panel.tsx +27 -6
  291. package/_standalone/components/Sidebar.tsx +1 -1
  292. package/_standalone/components/SidebarLayout.tsx +30 -7
  293. package/_standalone/components/SystemPulse.tsx +16 -16
  294. package/_standalone/components/agents/AgentsOverviewSection.tsx +18 -92
  295. package/_standalone/components/agents/AgentsPanelA2aTab.tsx +67 -66
  296. package/_standalone/components/agents/AgentsPrimitives.tsx +1 -1
  297. package/_standalone/components/agents/RecentActivityFeed.tsx +6 -6
  298. package/_standalone/components/agents/SkillDetailPopover.tsx +1 -1
  299. package/_standalone/components/ask/AskHeader.tsx +1 -1
  300. package/_standalone/components/echo/EchoHero.tsx +1 -1
  301. package/_standalone/components/echo/EchoPageSections.tsx +1 -1
  302. package/_standalone/components/explore/UseCaseCard.tsx +1 -1
  303. package/_standalone/components/home/InboxSection.tsx +262 -54
  304. package/_standalone/components/panels/AgentsPanel.tsx +4 -3
  305. package/_standalone/components/panels/AgentsPanelAgentDetail.tsx +1 -1
  306. package/_standalone/components/panels/AgentsPanelHubNav.tsx +10 -6
  307. package/_standalone/components/panels/PanelHeader.tsx +1 -1
  308. package/_standalone/components/renderers/audio/AudioRenderer.tsx +79 -0
  309. package/_standalone/components/renderers/image/ImageRenderer.tsx +203 -0
  310. package/_standalone/components/renderers/pdf/PdfRenderer.tsx +57 -0
  311. package/_standalone/components/renderers/video/VideoRenderer.tsx +91 -0
  312. package/_standalone/components/settings/McpTab.tsx +154 -28
  313. package/_standalone/components/settings/PluginsTab.tsx +1 -1
  314. package/_standalone/components/settings/SettingsContent.tsx +41 -7
  315. package/_standalone/components/settings/types.ts +7 -1
  316. package/_standalone/components/walkthrough/WalkthroughOverlay.tsx +40 -11
  317. package/_standalone/components/walkthrough/WalkthroughTooltip.tsx +1 -1
  318. package/_standalone/hooks/useAiOrganize.ts +14 -1
  319. package/_standalone/lib/organize-history.ts +6 -0
  320. package/_standalone/lib/stores/walkthrough-store.ts +33 -1
  321. package/_standalone/tsconfig.tsbuildinfo +1 -1
  322. package/app/app/api/ask/route.ts +193 -3
  323. package/app/app/api/file/raw/route.ts +121 -0
  324. package/app/app/api/file/route.ts +21 -0
  325. package/app/app/api/inbox/route.ts +38 -2
  326. package/app/app/api/mcp/status/route.ts +1 -0
  327. package/app/app/api/restart/route.ts +26 -21
  328. package/app/app/api/settings/route.ts +13 -0
  329. package/app/app/api/setup/route.ts +11 -1
  330. package/app/app/api/sync/route.ts +36 -13
  331. package/app/app/api/update/route.ts +24 -10
  332. package/app/app/global-error.tsx +3 -3
  333. package/app/app/globals.css +29 -3
  334. package/app/app/inbox/history/page.tsx +250 -0
  335. package/app/app/layout.tsx +5 -11
  336. package/app/app/login/page.tsx +1 -1
  337. package/app/app/view/[...path]/ViewPageClient.tsx +15 -10
  338. package/app/app/view/[...path]/not-found.tsx +1 -1
  339. package/app/app/view/[...path]/page.tsx +32 -1
  340. package/app/app/wiki/page.tsx +58 -0
  341. package/app/components/ActivityBar.tsx +9 -9
  342. package/app/components/AskFab.tsx +1 -1
  343. package/app/components/Backlinks.tsx +1 -1
  344. package/app/components/Breadcrumb.tsx +1 -1
  345. package/app/components/CreateSpaceModal.tsx +1 -1
  346. package/app/components/DirView.tsx +2 -2
  347. package/app/components/EchoSpotlight.tsx +14 -10
  348. package/app/components/Editor.tsx +1 -1
  349. package/app/components/ExportModal.tsx +3 -3
  350. package/app/components/FileTree.tsx +6 -11
  351. package/app/components/GuideCard.tsx +1 -1
  352. package/app/components/HomeContent.tsx +50 -39
  353. package/app/components/ImportModal.tsx +1 -2
  354. package/app/components/KeyboardShortcuts.tsx +1 -1
  355. package/app/components/MarkdownEditor.tsx +1 -1
  356. package/app/components/OnboardingView.tsx +2 -2
  357. package/app/components/OrganizeToast.tsx +3 -1
  358. package/app/components/Panel.tsx +27 -6
  359. package/app/components/Sidebar.tsx +1 -1
  360. package/app/components/SidebarLayout.tsx +30 -7
  361. package/app/components/SystemPulse.tsx +16 -16
  362. package/app/components/TrashPageClient.tsx +8 -6
  363. package/app/components/UpdateOverlay.tsx +1 -1
  364. package/app/components/WikiHomeContent.tsx +273 -0
  365. package/app/components/agents/AgentDetailContent.tsx +5 -5
  366. package/app/components/agents/AgentsContentPage.tsx +14 -3
  367. package/app/components/agents/AgentsOverviewSection.tsx +18 -92
  368. package/app/components/agents/AgentsPanelA2aTab.tsx +67 -66
  369. package/app/components/agents/AgentsPrimitives.tsx +1 -1
  370. package/app/components/agents/RecentActivityFeed.tsx +6 -6
  371. package/app/components/agents/SkillDetailPopover.tsx +1 -1
  372. package/app/components/agents/agents-content-model.ts +4 -1
  373. package/app/components/ask/AskHeader.tsx +1 -1
  374. package/app/components/changes/ChangesContentPage.tsx +10 -6
  375. package/app/components/echo/EchoHero.tsx +1 -1
  376. package/app/components/echo/EchoPageSections.tsx +1 -1
  377. package/app/components/explore/ExploreContent.tsx +1 -1
  378. package/app/components/explore/UseCaseCard.tsx +1 -1
  379. package/app/components/help/HelpContent.tsx +3 -3
  380. package/app/components/home/InboxSection.tsx +262 -54
  381. package/app/components/panels/AgentsPanel.tsx +4 -3
  382. package/app/components/panels/AgentsPanelAgentDetail.tsx +1 -1
  383. package/app/components/panels/AgentsPanelHubNav.tsx +10 -6
  384. package/app/components/panels/PanelHeader.tsx +1 -1
  385. package/app/components/renderers/audio/AudioRenderer.tsx +79 -0
  386. package/app/components/renderers/audio/manifest.ts +17 -0
  387. package/app/components/renderers/image/ImageRenderer.tsx +203 -0
  388. package/app/components/renderers/image/manifest.ts +17 -0
  389. package/app/components/renderers/pdf/PdfRenderer.tsx +57 -0
  390. package/app/components/renderers/pdf/manifest.ts +15 -0
  391. package/app/components/renderers/video/VideoRenderer.tsx +91 -0
  392. package/app/components/renderers/video/manifest.ts +17 -0
  393. package/app/components/settings/McpTab.tsx +154 -28
  394. package/app/components/settings/PluginsTab.tsx +1 -1
  395. package/app/components/settings/SettingsContent.tsx +41 -7
  396. package/app/components/settings/types.ts +7 -1
  397. package/app/components/setup/index.tsx +4 -3
  398. package/app/components/walkthrough/WalkthroughOverlay.tsx +40 -11
  399. package/app/components/walkthrough/WalkthroughTooltip.tsx +1 -1
  400. package/app/hooks/useAiOrganize.ts +14 -1
  401. package/app/lib/agent/model.ts +2 -1
  402. package/app/lib/core/inbox.ts +131 -2
  403. package/app/lib/core/pdf-text.ts +28 -0
  404. package/app/lib/core/search-index.ts +29 -5
  405. package/app/lib/core/tree.ts +6 -1
  406. package/app/lib/fs.ts +31 -3
  407. package/app/lib/i18n/modules/ai-chat.ts +42 -0
  408. package/app/lib/i18n/modules/knowledge.ts +30 -0
  409. package/app/lib/i18n/modules/navigation.ts +4 -2
  410. package/app/lib/i18n/modules/panels.ts +22 -4
  411. package/app/lib/i18n/modules/settings.ts +26 -0
  412. package/app/lib/organize-history.ts +6 -0
  413. package/app/lib/renderers/index.ts +5 -1
  414. package/app/lib/settings.ts +60 -0
  415. package/app/lib/stores/walkthrough-store.ts +33 -1
  416. package/bin/commands/doctor.js +12 -6
  417. package/bin/commands/file.js +7 -4
  418. package/bin/commands/logs.js +39 -4
  419. package/bin/commands/onboard.js +1 -1
  420. package/bin/commands/open.js +6 -1
  421. package/bin/commands/space.js +7 -4
  422. package/bin/commands/update.js +31 -29
  423. package/bin/lib/build.js +19 -8
  424. package/bin/lib/clean-env.js +38 -0
  425. package/bin/lib/cli-shim.js +67 -2
  426. package/bin/lib/config.js +4 -5
  427. package/bin/lib/gateway.js +51 -27
  428. package/bin/lib/jsonc.js +7 -2
  429. package/bin/lib/mcp-agents.js +26 -5
  430. package/bin/lib/path-expand.js +6 -3
  431. package/bin/lib/port.js +5 -1
  432. package/bin/lib/stop.js +98 -41
  433. package/bin/lib/sync.js +1 -1
  434. package/package.json +1 -1
  435. package/scripts/setup.js +7 -5
  436. package/_standalone/.next/server/chunks/2673.js +0 -52
  437. package/_standalone/.next/server/chunks/5648.js +0 -2
  438. package/_standalone/.next/server/chunks/8408.js +0 -219
  439. package/_standalone/.next/static/IiTZbEzZo8l5MSUxlDwKp/_buildManifest.js +0 -1
  440. package/_standalone/.next/static/chunks/1053-c519cb347faa75e2.js +0 -29
  441. package/_standalone/.next/static/chunks/1814.72f7fe7c61e2b647.js +0 -1
  442. package/_standalone/.next/static/chunks/362.4c226d7887d5f696.js +0 -1
  443. package/_standalone/.next/static/chunks/6357-c645842834c0d4cd.js +0 -1
  444. package/_standalone/.next/static/chunks/6981-3d7dcac2d12a5670.js +0 -1
  445. package/_standalone/.next/static/chunks/7035-032641fb6f4e07b2.js +0 -1
  446. package/_standalone/.next/static/chunks/7144-5febf62f1a79fe64.js +0 -1
  447. package/_standalone/.next/static/chunks/9602-423291fdb36396d1.js +0 -1
  448. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-074d6aafc2606561.js +0 -1
  449. package/_standalone/.next/static/chunks/app/agents/page-710d8c80fa86e93e.js +0 -5
  450. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-b07a5983e85bc5e3.js +0 -1
  451. package/_standalone/.next/static/chunks/app/api/a2a/route-b07a5983e85bc5e3.js +0 -1
  452. package/_standalone/.next/static/chunks/app/api/acp/config/route-b07a5983e85bc5e3.js +0 -1
  453. package/_standalone/.next/static/chunks/app/api/acp/detect/route-b07a5983e85bc5e3.js +0 -1
  454. package/_standalone/.next/static/chunks/app/api/acp/install/route-b07a5983e85bc5e3.js +0 -1
  455. package/_standalone/.next/static/chunks/app/api/acp/registry/route-b07a5983e85bc5e3.js +0 -1
  456. package/_standalone/.next/static/chunks/app/api/acp/session/route-b07a5983e85bc5e3.js +0 -1
  457. package/_standalone/.next/static/chunks/app/api/agent-activity/route-b07a5983e85bc5e3.js +0 -1
  458. package/_standalone/.next/static/chunks/app/api/ask/route-b07a5983e85bc5e3.js +0 -1
  459. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-b07a5983e85bc5e3.js +0 -1
  460. package/_standalone/.next/static/chunks/app/api/auth/route-b07a5983e85bc5e3.js +0 -1
  461. package/_standalone/.next/static/chunks/app/api/backlinks/route-b07a5983e85bc5e3.js +0 -1
  462. package/_standalone/.next/static/chunks/app/api/bootstrap/route-b07a5983e85bc5e3.js +0 -1
  463. package/_standalone/.next/static/chunks/app/api/changes/route-b07a5983e85bc5e3.js +0 -1
  464. package/_standalone/.next/static/chunks/app/api/export/route-b07a5983e85bc5e3.js +0 -1
  465. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-b07a5983e85bc5e3.js +0 -1
  466. package/_standalone/.next/static/chunks/app/api/file/import/route-b07a5983e85bc5e3.js +0 -1
  467. package/_standalone/.next/static/chunks/app/api/file/route-b07a5983e85bc5e3.js +0 -1
  468. package/_standalone/.next/static/chunks/app/api/files/route-b07a5983e85bc5e3.js +0 -1
  469. package/_standalone/.next/static/chunks/app/api/git/route-b07a5983e85bc5e3.js +0 -1
  470. package/_standalone/.next/static/chunks/app/api/graph/route-b07a5983e85bc5e3.js +0 -1
  471. package/_standalone/.next/static/chunks/app/api/health/route-b07a5983e85bc5e3.js +0 -1
  472. package/_standalone/.next/static/chunks/app/api/inbox/route-b07a5983e85bc5e3.js +0 -1
  473. package/_standalone/.next/static/chunks/app/api/init/route-b07a5983e85bc5e3.js +0 -1
  474. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-b07a5983e85bc5e3.js +0 -1
  475. package/_standalone/.next/static/chunks/app/api/mcp/install/route-b07a5983e85bc5e3.js +0 -1
  476. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-b07a5983e85bc5e3.js +0 -1
  477. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-b07a5983e85bc5e3.js +0 -1
  478. package/_standalone/.next/static/chunks/app/api/mcp/status/route-b07a5983e85bc5e3.js +0 -1
  479. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-b07a5983e85bc5e3.js +0 -1
  480. package/_standalone/.next/static/chunks/app/api/monitoring/route-b07a5983e85bc5e3.js +0 -1
  481. package/_standalone/.next/static/chunks/app/api/recent-files/route-b07a5983e85bc5e3.js +0 -1
  482. package/_standalone/.next/static/chunks/app/api/restart/route-b07a5983e85bc5e3.js +0 -1
  483. package/_standalone/.next/static/chunks/app/api/search/route-b07a5983e85bc5e3.js +0 -1
  484. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-b07a5983e85bc5e3.js +0 -1
  485. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-b07a5983e85bc5e3.js +0 -1
  486. package/_standalone/.next/static/chunks/app/api/settings/route-b07a5983e85bc5e3.js +0 -1
  487. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-b07a5983e85bc5e3.js +0 -1
  488. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-b07a5983e85bc5e3.js +0 -1
  489. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-b07a5983e85bc5e3.js +0 -1
  490. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-b07a5983e85bc5e3.js +0 -1
  491. package/_standalone/.next/static/chunks/app/api/setup/ls/route-b07a5983e85bc5e3.js +0 -1
  492. package/_standalone/.next/static/chunks/app/api/setup/route-b07a5983e85bc5e3.js +0 -1
  493. package/_standalone/.next/static/chunks/app/api/skills/route-b07a5983e85bc5e3.js +0 -1
  494. package/_standalone/.next/static/chunks/app/api/sync/route-b07a5983e85bc5e3.js +0 -1
  495. package/_standalone/.next/static/chunks/app/api/tree-version/route-b07a5983e85bc5e3.js +0 -1
  496. package/_standalone/.next/static/chunks/app/api/uninstall/route-b07a5983e85bc5e3.js +0 -1
  497. package/_standalone/.next/static/chunks/app/api/update/route-b07a5983e85bc5e3.js +0 -1
  498. package/_standalone/.next/static/chunks/app/api/update-check/route-b07a5983e85bc5e3.js +0 -1
  499. package/_standalone/.next/static/chunks/app/api/update-status/route-b07a5983e85bc5e3.js +0 -1
  500. package/_standalone/.next/static/chunks/app/api/workflows/route-b07a5983e85bc5e3.js +0 -1
  501. package/_standalone/.next/static/chunks/app/changes/page-350992cf5091bc5b.js +0 -1
  502. package/_standalone/.next/static/chunks/app/echo/page-b07a5983e85bc5e3.js +0 -1
  503. package/_standalone/.next/static/chunks/app/global-error-e1ad0e18236ba26c.js +0 -1
  504. package/_standalone/.next/static/chunks/app/help/page-2325d25b6846ca07.js +0 -1
  505. package/_standalone/.next/static/chunks/app/layout-e706f9a963b177ba.js +0 -186
  506. package/_standalone/.next/static/chunks/app/loading-b07a5983e85bc5e3.js +0 -1
  507. package/_standalone/.next/static/chunks/app/page-2595175820acfd65.js +0 -7
  508. package/_standalone/.next/static/chunks/app/trash/page-61c6210fac1e9710.js +0 -1
  509. package/_standalone/.next/static/chunks/app/view/[...path]/loading-b07a5983e85bc5e3.js +0 -1
  510. package/_standalone/.next/static/chunks/app/view/[...path]/not-found-61474670d6bb6116.js +0 -1
  511. package/_standalone/.next/static/chunks/app/view/[...path]/page-798359c36f10ef8d.js +0 -12
  512. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-b07a5983e85bc5e3.js +0 -1
  513. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-b07a5983e85bc5e3.js +0 -1
  514. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-b07a5983e85bc5e3.js +0 -1
  515. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-b07a5983e85bc5e3.js +0 -1
  516. package/_standalone/.next/static/css/bbf51803eade6c50.css +0 -31
  517. package/_standalone/.next/static/css/ef1151f74f00d91a.css +0 -1
  518. package/_standalone/lib/i18n/generated/explore-i18n.generated.ts +0 -138
  519. package/_standalone/lib/i18n/index.ts +0 -38
  520. package/_standalone/lib/i18n/modules/ai-chat.ts +0 -237
  521. package/_standalone/lib/i18n/modules/common.ts +0 -71
  522. package/_standalone/lib/i18n/modules/features.ts +0 -153
  523. package/_standalone/lib/i18n/modules/knowledge.ts +0 -727
  524. package/_standalone/lib/i18n/modules/navigation.ts +0 -157
  525. package/_standalone/lib/i18n/modules/onboarding.ts +0 -445
  526. package/_standalone/lib/i18n/modules/panels.ts +0 -1255
  527. package/_standalone/lib/i18n/modules/settings.ts +0 -889
  528. package/_standalone/lib/i18n.ts +0 -3
  529. /package/_standalone/.next/static/{IiTZbEzZo8l5MSUxlDwKp → 2hrwFOLEOZhHQHfrIt-Dw}/_ssgManifest.js +0 -0
@@ -11,10 +11,15 @@ import {
11
11
  Loader2,
12
12
  ChevronRight,
13
13
  Upload,
14
+ FolderInput,
15
+ Check,
16
+ Clock,
17
+ ChevronDown,
14
18
  } from 'lucide-react';
15
19
  import { useLocale } from '@/lib/stores/locale-store';
16
20
  import { encodePath } from '@/lib/utils';
17
21
  import { quickDropToInbox } from '@/lib/inbox-upload';
22
+ import { loadHistory, type OrganizeHistoryEntry, type OrganizeSource } from '@/lib/organize-history';
18
23
 
19
24
  interface InboxFile {
20
25
  name: string;
@@ -29,14 +34,17 @@ interface InboxSectionProps {
29
34
  }
30
35
 
31
36
  const VISIBLE_LIMIT = 5;
37
+ const HISTORY_LIMIT = 3;
32
38
 
33
39
  export function InboxSection({ isOrganizing: externalOrganizing = false }: InboxSectionProps) {
34
40
  const { t } = useLocale();
35
41
  const [files, setFiles] = useState<InboxFile[]>([]);
36
42
  const [loading, setLoading] = useState(true);
37
- const [showAll, setShowAll] = useState(false);
38
43
  const [organizing, setOrganizing] = useState(false);
44
+ const [dragOver, setDragOver] = useState(false);
45
+ const [history, setHistory] = useState<OrganizeHistoryEntry[]>([]);
39
46
  const fileInputRef = useRef<HTMLInputElement>(null);
47
+ const dragCounterRef = useRef(0);
40
48
  const isOrganizing = externalOrganizing || organizing;
41
49
 
42
50
  const handleOrganize = useCallback(() => {
@@ -53,6 +61,16 @@ export function InboxSection({ isOrganizing: externalOrganizing = false }: Inbox
53
61
  if (fileInputRef.current) fileInputRef.current.value = '';
54
62
  }, [t]);
55
63
 
64
+ const handleLocalDrop = useCallback((e: React.DragEvent) => {
65
+ e.preventDefault();
66
+ e.stopPropagation();
67
+ dragCounterRef.current = 0;
68
+ setDragOver(false);
69
+ if (e.dataTransfer.files.length > 0) {
70
+ quickDropToInbox(Array.from(e.dataTransfer.files), t);
71
+ }
72
+ }, [t]);
73
+
56
74
  const fetchInbox = useCallback(async () => {
57
75
  try {
58
76
  const res = await fetch('/api/inbox');
@@ -68,33 +86,59 @@ export function InboxSection({ isOrganizing: externalOrganizing = false }: Inbox
68
86
  }
69
87
  }, []);
70
88
 
89
+ const refreshHistory = useCallback(() => {
90
+ setHistory(loadHistory().slice(0, HISTORY_LIMIT));
91
+ }, []);
92
+
71
93
  const refreshTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
72
94
  const debouncedRefresh = useCallback(() => {
73
95
  clearTimeout(refreshTimerRef.current);
74
- refreshTimerRef.current = setTimeout(fetchInbox, 80);
75
- }, [fetchInbox]);
96
+ refreshTimerRef.current = setTimeout(() => {
97
+ fetchInbox();
98
+ refreshHistory();
99
+ }, 80);
100
+ }, [fetchInbox, refreshHistory]);
101
+
102
+ useEffect(() => {
103
+ const resetDrag = () => { dragCounterRef.current = 0; setDragOver(false); };
104
+ window.addEventListener('drop', resetDrag, true);
105
+ window.addEventListener('dragend', resetDrag, true);
106
+ return () => {
107
+ window.removeEventListener('drop', resetDrag, true);
108
+ window.removeEventListener('dragend', resetDrag, true);
109
+ };
110
+ }, []);
76
111
 
77
112
  useEffect(() => {
78
113
  fetchInbox();
114
+ refreshHistory();
79
115
 
80
116
  const onOrganizeDone = () => { setOrganizing(false); debouncedRefresh(); };
81
117
 
82
118
  window.addEventListener('mindos:files-changed', debouncedRefresh);
83
119
  window.addEventListener('mindos:inbox-updated', debouncedRefresh);
84
120
  window.addEventListener('mindos:organize-done', onOrganizeDone);
121
+ window.addEventListener('mindos:organize-history-update', refreshHistory);
85
122
  return () => {
86
123
  clearTimeout(refreshTimerRef.current);
87
124
  window.removeEventListener('mindos:files-changed', debouncedRefresh);
88
125
  window.removeEventListener('mindos:inbox-updated', debouncedRefresh);
89
126
  window.removeEventListener('mindos:organize-done', onOrganizeDone);
127
+ window.removeEventListener('mindos:organize-history-update', refreshHistory);
90
128
  };
91
- }, [fetchInbox, debouncedRefresh]);
129
+ }, [fetchInbox, debouncedRefresh, refreshHistory]);
92
130
 
93
131
  const visibleFiles = useMemo(
94
- () => (showAll ? files : files.slice(0, VISIBLE_LIMIT)),
95
- [files, showAll],
132
+ () => files.slice(0, VISIBLE_LIMIT),
133
+ [files],
96
134
  );
97
- const hiddenCount = files.length - VISIBLE_LIMIT;
135
+ const overflowCount = Math.max(0, files.length - VISIBLE_LIMIT);
136
+ const hasFiles = files.length > 0;
137
+ const [totalHistory, setTotalHistory] = useState(0);
138
+
139
+ useEffect(() => {
140
+ setTotalHistory(loadHistory().length);
141
+ }, [history]);
98
142
 
99
143
  if (loading) return (
100
144
  <section className="mb-10 animate-pulse">
@@ -109,32 +153,33 @@ export function InboxSection({ isOrganizing: externalOrganizing = false }: Inbox
109
153
  return (
110
154
  <section className="mb-10">
111
155
  {/* Header */}
112
- <div className="flex items-center gap-2 mb-4">
113
- <span className="text-[var(--amber)]">
156
+ <div className="flex items-center gap-2.5 mb-5">
157
+ <div className="flex items-center justify-center w-6 h-6 rounded-md bg-[var(--amber-subtle)] text-[var(--amber)]">
114
158
  <Inbox size={13} />
115
- </span>
116
- <h2 className="text-sm font-semibold font-display text-foreground">
159
+ </div>
160
+ <h2 className="text-[13px] font-semibold text-foreground tracking-wide">
117
161
  {t.inbox.title}
118
162
  </h2>
119
- {files.length > 0 && (
120
- <span className="inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 text-2xs font-semibold rounded-full bg-[var(--amber)]/15 text-[var(--amber)] tabular-nums font-display">
163
+ {hasFiles && (
164
+ <span className="inline-flex items-center justify-center min-w-[20px] h-5 px-1.5 text-[10px] font-semibold rounded-full bg-muted text-muted-foreground tabular-nums">
121
165
  {t.inbox.count(files.length)}
122
166
  </span>
123
167
  )}
124
- {files.length > 0 && (
168
+ {hasFiles && (
125
169
  <div className="ml-auto flex items-center gap-3">
126
170
  <button
127
171
  type="button"
128
172
  onClick={() => fileInputRef.current?.click()}
129
- className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground cursor-pointer font-display"
173
+ className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground cursor-pointer"
130
174
  title={t.inbox.uploadButton}
131
175
  >
132
176
  <Upload size={12} />
177
+ <span className="hidden sm:inline">{t.inbox.uploadButton}</span>
133
178
  </button>
134
179
  <button
135
180
  onClick={handleOrganize}
136
181
  disabled={isOrganizing}
137
- className="flex items-center gap-1.5 text-xs font-medium text-[var(--amber)] transition-colors hover:opacity-80 cursor-pointer font-display disabled:opacity-50 disabled:cursor-not-allowed"
182
+ className="flex items-center gap-1.5 text-xs font-medium text-[var(--amber)] transition-colors hover:opacity-80 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
138
183
  title={isOrganizing ? t.inbox.organizing : undefined}
139
184
  >
140
185
  {isOrganizing ? (
@@ -148,7 +193,7 @@ export function InboxSection({ isOrganizing: externalOrganizing = false }: Inbox
148
193
  )}
149
194
  </div>
150
195
 
151
- {/* Hidden file input for upload button */}
196
+ {/* Hidden file input */}
152
197
  <input
153
198
  ref={fileInputRef}
154
199
  type="file"
@@ -158,46 +203,111 @@ export function InboxSection({ isOrganizing: externalOrganizing = false }: Inbox
158
203
  onChange={(e) => handleUpload(e.target.files)}
159
204
  />
160
205
 
161
- {/* Content drag-drop is handled by SidebarLayout's global overlay */}
162
- {files.length === 0 ? (
163
- <div className="rounded-xl border-2 border-dashed border-border px-4 py-8 text-center">
164
- <Inbox size={24} className="mx-auto mb-2 text-muted-foreground/30" />
165
- <p className="text-sm text-muted-foreground/70 font-display">
166
- {t.inbox.emptyTitle}
167
- </p>
168
- <p className="text-xs text-muted-foreground/40 mt-1">
169
- {t.inbox.emptyDesc}
170
- </p>
171
- <button
172
- type="button"
173
- onClick={() => fileInputRef.current?.click()}
174
- className="mt-3 inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg transition-colors bg-muted text-muted-foreground hover:text-foreground hover:bg-muted/80"
175
- >
176
- <Upload size={12} />
177
- {t.inbox.uploadButton}
178
- </button>
179
- </div>
180
- ) : (
206
+ {/* File list */}
207
+ {hasFiles && (
181
208
  <>
182
- <div className="flex flex-col gap-0.5">
209
+ <div className="flex flex-col gap-0.5 mb-3">
183
210
  {visibleFiles.map((file) => (
184
211
  <InboxFileRow key={file.path} file={file} />
185
212
  ))}
186
213
  </div>
187
- {hiddenCount > 0 && (
188
- <button
189
- onClick={() => setShowAll(v => !v)}
190
- className="flex items-center gap-1 mt-2 text-xs text-muted-foreground hover:text-foreground transition-colors cursor-pointer font-display"
214
+ {overflowCount > 0 && (
215
+ <Link
216
+ href="/view/Inbox/"
217
+ className="flex items-center gap-1 mb-3 text-xs text-muted-foreground hover:text-[var(--amber)] transition-colors"
191
218
  >
192
- <ChevronRight
193
- size={12}
194
- className={`transition-transform duration-150 ${showAll ? 'rotate-90' : ''}`}
195
- />
196
- {showAll ? t.home.showLess : t.inbox.more(hiddenCount)}
197
- </button>
219
+ <ChevronRight size={12} />
220
+ {t.inbox.viewAllFiles(files.length)}
221
+ </Link>
198
222
  )}
199
223
  </>
200
224
  )}
225
+
226
+ {/* Drop zone — always visible */}
227
+ <div
228
+ className={`rounded-xl border-2 border-dashed transition-all duration-200 cursor-pointer ${
229
+ dragOver
230
+ ? 'border-[var(--amber)] bg-[var(--amber-subtle)]'
231
+ : hasFiles
232
+ ? 'border-border/60 hover:border-[var(--amber)]/40'
233
+ : 'border-border hover:border-[var(--amber)]/40'
234
+ } ${hasFiles ? 'px-4 py-4' : 'px-4 py-8'}`}
235
+ role="button"
236
+ tabIndex={0}
237
+ aria-label={t.inbox.uploadButton}
238
+ onClick={() => fileInputRef.current?.click()}
239
+ onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); fileInputRef.current?.click(); } }}
240
+ onDragEnter={(e) => {
241
+ if (!e.dataTransfer.types.includes('Files')) return;
242
+ e.preventDefault();
243
+ e.stopPropagation();
244
+ dragCounterRef.current++;
245
+ if (dragCounterRef.current === 1) setDragOver(true);
246
+ }}
247
+ onDragOver={(e) => {
248
+ if (!e.dataTransfer.types.includes('Files')) return;
249
+ e.preventDefault();
250
+ e.stopPropagation();
251
+ }}
252
+ onDragLeave={(e) => {
253
+ e.stopPropagation();
254
+ dragCounterRef.current = Math.max(0, dragCounterRef.current - 1);
255
+ if (dragCounterRef.current === 0) setDragOver(false);
256
+ }}
257
+ onDrop={handleLocalDrop}
258
+ >
259
+ {hasFiles ? (
260
+ <div className="flex items-center justify-center gap-2 text-center">
261
+ <FolderInput size={16} className={`shrink-0 ${dragOver ? 'text-[var(--amber)]' : 'text-muted-foreground/40'}`} />
262
+ <p className="text-xs text-muted-foreground">
263
+ {t.fileImport.dropzoneCompact}{' '}
264
+ <span className="text-[var(--amber)] hover:underline">{t.fileImport.dropzoneCompactButton}</span>
265
+ </p>
266
+ </div>
267
+ ) : (
268
+ <div className="flex flex-col items-center gap-2 text-center">
269
+ <FolderInput size={28} className={`${dragOver ? 'text-[var(--amber)]' : 'text-muted-foreground/20'}`} />
270
+ <p className="text-sm text-muted-foreground/70">
271
+ {t.inbox.emptyTitle}
272
+ </p>
273
+ <p className="text-xs text-muted-foreground/40">
274
+ {t.inbox.emptyDesc}
275
+ </p>
276
+ <p className="text-2xs text-muted-foreground/30">{t.inbox.dropOverlayFormats}</p>
277
+ <button
278
+ type="button"
279
+ onClick={(e) => { e.stopPropagation(); fileInputRef.current?.click(); }}
280
+ className="mt-1 inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg transition-colors bg-muted text-muted-foreground hover:text-foreground hover:bg-muted/80"
281
+ >
282
+ <Upload size={12} />
283
+ {t.inbox.uploadButton}
284
+ </button>
285
+ </div>
286
+ )}
287
+ </div>
288
+
289
+ {/* Recently processed — inline history */}
290
+ {history.length > 0 && (
291
+ <div className="mt-4">
292
+ <div className="flex items-center gap-2 mb-2">
293
+ <Clock size={11} className="text-muted-foreground/40" />
294
+ <span className="text-2xs font-medium text-muted-foreground/60 uppercase tracking-wider">
295
+ {t.importHistory.title}
296
+ </span>
297
+ <Link
298
+ href="/inbox/history"
299
+ className="ml-auto text-2xs text-muted-foreground/50 hover:text-[var(--amber)] transition-colors"
300
+ >
301
+ {t.inbox.viewAllHistory(totalHistory)}
302
+ </Link>
303
+ </div>
304
+ <div className="flex flex-col gap-1">
305
+ {history.map((entry) => (
306
+ <HistoryRow key={entry.id} entry={entry} />
307
+ ))}
308
+ </div>
309
+ </div>
310
+ )}
201
311
  </section>
202
312
  );
203
313
  }
@@ -212,19 +322,16 @@ function InboxFileRow({ file }: { file: InboxFile }) {
212
322
  href={`/view/${encodePath(file.path)}`}
213
323
  className="flex items-center gap-3 px-3 py-2 rounded-lg transition-all duration-100 hover:translate-x-0.5 hover:bg-muted group"
214
324
  >
215
- {/* Dot indicator */}
216
325
  <span
217
326
  className={`w-1.5 h-1.5 rounded-full shrink-0 ${
218
327
  file.isAging ? 'bg-[var(--amber)]/60' : 'bg-[var(--amber)]'
219
328
  }`}
220
329
  />
221
- {/* Icon */}
222
330
  {isCSV ? (
223
331
  <Table size={12} className="shrink-0 text-success" />
224
332
  ) : (
225
333
  <FileText size={12} className="shrink-0 text-muted-foreground" />
226
334
  )}
227
- {/* Name */}
228
335
  <span
229
336
  className="text-sm truncate flex-1 text-foreground"
230
337
  title={file.name}
@@ -232,11 +339,9 @@ function InboxFileRow({ file }: { file: InboxFile }) {
232
339
  >
233
340
  {file.name}
234
341
  </span>
235
- {/* Time */}
236
- <span className="text-2xs text-muted-foreground/50 tabular-nums shrink-0 font-display">
342
+ <span className="text-2xs text-muted-foreground/50 tabular-nums shrink-0">
237
343
  {age}
238
344
  </span>
239
- {/* Aging warning */}
240
345
  {file.isAging && (
241
346
  <span title="7+ days">
242
347
  <AlertCircle
@@ -249,6 +354,109 @@ function InboxFileRow({ file }: { file: InboxFile }) {
249
354
  );
250
355
  }
251
356
 
357
+ function HistoryRow({ entry }: { entry: OrganizeHistoryEntry }) {
358
+ const [expanded, setExpanded] = useState(false);
359
+ const isUndone = entry.status === 'undone';
360
+ const sourceBadge = getSourceBadge(entry.source);
361
+ const duration = entry.durationMs ? formatDuration(entry.durationMs) : null;
362
+ const age = formatRelativeTime(new Date(entry.timestamp).toISOString(), {
363
+ justNow: 'just now',
364
+ minutesAgo: (n: number) => `${n}m ago`,
365
+ hoursAgo: (n: number) => `${n}h ago`,
366
+ daysAgo: (n: number) => `${n}d ago`,
367
+ });
368
+
369
+ return (
370
+ <div className="rounded-lg border border-border/30 overflow-hidden">
371
+ <button
372
+ type="button"
373
+ onClick={() => setExpanded(v => !v)}
374
+ className="w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-muted/20 transition-colors"
375
+ >
376
+ {isUndone ? (
377
+ <AlertCircle size={12} className="text-muted-foreground/40 shrink-0" />
378
+ ) : (
379
+ <Check size={12} className="text-success/70 shrink-0" />
380
+ )}
381
+ <div className="flex-1 min-w-0 flex items-center gap-1.5">
382
+ <span className={`text-xs truncate ${isUndone ? 'text-muted-foreground/50 line-through' : 'text-foreground/80'}`}>
383
+ {entry.sourceFiles.length === 1 ? entry.sourceFiles[0] : `${entry.sourceFiles.length} files`}
384
+ </span>
385
+ {sourceBadge && (
386
+ <span className={`text-2xs px-1.5 py-0.5 rounded shrink-0 ${sourceBadge.className}`}>
387
+ {sourceBadge.label}
388
+ </span>
389
+ )}
390
+ </div>
391
+ <span className="text-2xs text-muted-foreground/40 tabular-nums shrink-0">
392
+ {duration && `${duration} · `}{age}
393
+ </span>
394
+ {entry.files.length > 0 && (
395
+ <ChevronDown
396
+ size={10}
397
+ className={`text-muted-foreground/30 shrink-0 transition-transform duration-150 ${expanded ? 'rotate-180' : ''}`}
398
+ />
399
+ )}
400
+ </button>
401
+
402
+ {expanded && entry.files.length > 0 && (
403
+ <div className="border-t border-border/20 px-3 py-1.5 space-y-0.5">
404
+ {entry.files.map((f, idx) => {
405
+ const parts = f.path.split('/');
406
+ const fileName = parts.pop() ?? f.path;
407
+ const dirPath = parts.length > 0 ? parts.join('/') : null;
408
+ const isClickable = !f.undone && f.ok;
409
+ const rowClass = `flex items-center gap-2 py-1 text-2xs${f.undone ? ' opacity-40' : ''}${isClickable ? ' rounded -mx-1 px-1 hover:bg-muted/20 transition-colors' : ''}`;
410
+ const rowContent = (
411
+ <>
412
+ <span className={`w-1 h-1 rounded-full shrink-0 ${f.ok && !f.undone ? 'bg-success/60' : 'bg-muted-foreground/30'}`} />
413
+ <span className={`truncate flex-1 min-w-0 ${f.undone ? 'line-through text-muted-foreground' : ''}`}>
414
+ {dirPath && (
415
+ <span className="text-muted-foreground/30">{dirPath}/</span>
416
+ )}
417
+ <span className={f.undone ? '' : 'text-foreground/70'}>{fileName}</span>
418
+ </span>
419
+ <span className="text-muted-foreground/40 shrink-0">
420
+ {f.undone ? 'undone' : f.action === 'create' ? 'created' : 'updated'}
421
+ </span>
422
+ </>
423
+ );
424
+ return isClickable ? (
425
+ <Link key={`${f.path}-${idx}`} href={`/view/${encodePath(f.path)}`} className={rowClass}>
426
+ {rowContent}
427
+ </Link>
428
+ ) : (
429
+ <div key={`${f.path}-${idx}`} className={rowClass}>
430
+ {rowContent}
431
+ </div>
432
+ );
433
+ })}
434
+ </div>
435
+ )}
436
+ </div>
437
+ );
438
+ }
439
+
440
+ function getSourceBadge(source?: OrganizeSource): { label: string; className: string } | null {
441
+ switch (source) {
442
+ case 'drag-drop': return { label: 'drop', className: 'bg-muted/50 text-muted-foreground/50' };
443
+ case 'inbox-organize': return { label: 'inbox', className: 'bg-[var(--amber)]/10 text-[var(--amber)]/70' };
444
+ case 'import-modal': return { label: 'import', className: 'bg-blue-500/10 text-blue-500/70' };
445
+ case 'plugin': return { label: 'plugin', className: 'bg-violet-500/10 text-violet-500/70' };
446
+ case 'upload': return { label: 'upload', className: 'bg-teal-500/10 text-teal-500/70' };
447
+ case 'web-clipper': return { label: 'clip', className: 'bg-emerald-500/10 text-emerald-500/70' };
448
+ default: return null;
449
+ }
450
+ }
451
+
452
+ function formatDuration(ms: number): string {
453
+ const s = Math.round(ms / 1000);
454
+ if (s < 60) return `${s}s`;
455
+ const m = Math.floor(s / 60);
456
+ const rem = s % 60;
457
+ return `${m}m${rem > 0 ? `${rem}s` : ''}`;
458
+ }
459
+
252
460
  interface RelativeTimeStrings {
253
461
  justNow: string;
254
462
  minutesAgo: (n: number) => string;
@@ -79,6 +79,7 @@ export default function AgentsPanel({
79
79
  <AgentsPanelHubNav
80
80
  copy={hubCopy}
81
81
  connectedCount={connected.length}
82
+ mcpEnabled={mcp.status?.connectionMode?.mcp ?? false}
82
83
  />
83
84
  );
84
85
 
@@ -116,9 +117,9 @@ export default function AgentsPanel({
116
117
  <div className="flex flex-col gap-2 py-4 px-0">
117
118
  {hub}
118
119
  <div className="mx-4 border-t border-border" />
119
- <div className="mx-3 rounded-lg border border-dashed border-border px-3 py-4 text-center">
120
- <p className="text-xs text-muted-foreground mb-1.5">{p.noAgents}</p>
121
- <p className="text-2xs text-muted-foreground mb-3">{p.skillsEmptyHint}</p>
120
+ <div className="mx-3 rounded-lg border border-border/40 bg-card/30 px-3 py-5 text-center">
121
+ <p className="text-xs text-muted-foreground/70 mb-1.5">{p.noAgents}</p>
122
+ <p className="text-2xs text-muted-foreground/40 mb-3">{p.skillsEmptyHint}</p>
122
123
  <button
123
124
  onClick={handleRefresh}
124
125
  type="button"
@@ -82,7 +82,7 @@ export default function AgentsPanelAgentDetail({
82
82
  <header className="shrink-0 flex items-center justify-between gap-3 border-b border-border px-4 py-3 bg-card">
83
83
  <div className="flex items-center gap-2.5 min-w-0">
84
84
  <span className={`w-2 h-2 rounded-full shrink-0 ${dot}`} />
85
- <h2 className="text-sm font-semibold text-foreground truncate font-display" title={agent.name}>{agent.name}</h2>
85
+ <h2 className="text-sm font-semibold text-foreground truncate" title={agent.name}>{agent.name}</h2>
86
86
  </div>
87
87
  <button
88
88
  type="button"
@@ -16,9 +16,11 @@ type HubCopy = {
16
16
  export function AgentsPanelHubNav({
17
17
  copy,
18
18
  connectedCount,
19
+ mcpEnabled = true,
19
20
  }: {
20
21
  copy: HubCopy;
21
22
  connectedCount: number;
23
+ mcpEnabled?: boolean;
22
24
  }) {
23
25
  const pathname = usePathname();
24
26
  const searchParams = useSearchParams();
@@ -34,12 +36,14 @@ export function AgentsPanelHubNav({
34
36
  href="/agents"
35
37
  active={inAgentsRoute && (tab === null || tab === 'overview')}
36
38
  />
37
- <PanelNavRow
38
- icon={<Server size={14} className={inAgentsRoute && tab === 'mcp' ? 'text-[var(--amber)]' : 'text-muted-foreground'} />}
39
- title={copy.navMcp}
40
- href="/agents?tab=mcp"
41
- active={inAgentsRoute && tab === 'mcp'}
42
- />
39
+ {mcpEnabled && (
40
+ <PanelNavRow
41
+ icon={<Server size={14} className={inAgentsRoute && tab === 'mcp' ? 'text-[var(--amber)]' : 'text-muted-foreground'} />}
42
+ title={copy.navMcp}
43
+ href="/agents?tab=mcp"
44
+ active={inAgentsRoute && tab === 'mcp'}
45
+ />
46
+ )}
43
47
  <PanelNavRow
44
48
  icon={<Zap size={14} className={inAgentsRoute && tab === 'skills' ? 'text-[var(--amber)]' : 'text-muted-foreground'} />}
45
49
  title={copy.navSkills}
@@ -17,7 +17,7 @@ export default function PanelHeader({
17
17
  }) {
18
18
  return (
19
19
  <div className="flex items-center justify-between px-4 py-3 h-[46px] border-b border-border shrink-0">
20
- <span className="text-xs font-medium text-muted-foreground uppercase tracking-wider font-display">{title}</span>
20
+ <span className="text-xs font-medium text-muted-foreground uppercase tracking-wider">{title}</span>
21
21
  <div className="flex items-center gap-1">
22
22
  {children}
23
23
  {onMaximize && (
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+
3
+ import { useState, useCallback, useEffect } from 'react';
4
+ import type { RendererContext } from '@/lib/renderers/registry';
5
+
6
+ function formatBytes(bytes: number): string {
7
+ if (bytes < 1024) return `${bytes} B`;
8
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
9
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
10
+ }
11
+
12
+ /**
13
+ * Audio Renderer — native HTML5 audio player with file info.
14
+ * Uses browser built-in controls (play/pause, seek, volume, speed).
15
+ * Supports Range requests for seeking in large files.
16
+ */
17
+ export function AudioRenderer({ filePath }: RendererContext) {
18
+ const src = `/api/file/raw?path=${encodeURIComponent(filePath)}`;
19
+ const fileName = filePath.split('/').pop() ?? 'audio';
20
+ const ext = fileName.split('.').pop()?.toLowerCase() ?? '';
21
+
22
+ const [error, setError] = useState(false);
23
+ const [retryKey, setRetryKey] = useState(0);
24
+ const [fileSize, setFileSize] = useState<number | null>(null);
25
+
26
+ useEffect(() => {
27
+ fetch(src, { method: 'HEAD' })
28
+ .then(res => {
29
+ const cl = res.headers.get('Content-Length');
30
+ if (cl) setFileSize(parseInt(cl, 10));
31
+ })
32
+ .catch(() => {});
33
+ }, [src]);
34
+
35
+ const handleRetry = useCallback(() => {
36
+ setError(false);
37
+ setRetryKey(k => k + 1);
38
+ }, []);
39
+
40
+ return (
41
+ <div className="w-full flex flex-col items-center gap-6 py-12 px-4">
42
+ {/* File info */}
43
+ <div className="flex items-center gap-3 text-xs text-[var(--text-secondary)]">
44
+ <span className="text-4xl opacity-40">🎵</span>
45
+ <div className="flex flex-col gap-0.5">
46
+ <span className="text-sm font-medium text-[var(--text-primary)]">{fileName}</span>
47
+ <div className="flex items-center gap-2">
48
+ <span className="uppercase opacity-60">{ext}</span>
49
+ {fileSize !== null && <span>{formatBytes(fileSize)}</span>}
50
+ </div>
51
+ </div>
52
+ </div>
53
+
54
+ {/* Player */}
55
+ {error ? (
56
+ <div className="flex flex-col items-center gap-2">
57
+ <span className="text-sm text-[var(--text-secondary)]">Failed to load audio</span>
58
+ <button
59
+ onClick={handleRetry}
60
+ className="text-xs px-3 py-1.5 rounded-md bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] transition-colors"
61
+ >
62
+ Retry
63
+ </button>
64
+ </div>
65
+ ) : (
66
+ /* eslint-disable-next-line jsx-a11y/media-has-caption */
67
+ <audio
68
+ key={retryKey}
69
+ controls
70
+ preload="metadata"
71
+ className="w-full max-w-lg"
72
+ onError={() => setError(true)}
73
+ >
74
+ <source src={src} />
75
+ </audio>
76
+ )}
77
+ </div>
78
+ );
79
+ }