@geminilight/mindos 0.6.59 → 0.6.61

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 (360) hide show
  1. package/_standalone/.mindos-build-version +1 -1
  2. package/_standalone/.next/BUILD_ID +1 -1
  3. package/_standalone/.next/app-path-routes-manifest.json +23 -22
  4. package/_standalone/.next/build-manifest.json +2 -2
  5. package/_standalone/.next/cache/.previewinfo +1 -1
  6. package/_standalone/.next/cache/.rscinfo +1 -1
  7. package/_standalone/.next/cache/config.json +3 -3
  8. package/_standalone/.next/prerender-manifest.json +3 -3
  9. package/_standalone/.next/routes-manifest.json +6 -0
  10. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  11. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/_standalone/.next/server/app/_global-error.html +2 -2
  13. package/_standalone/.next/server/app/_global-error.rsc +1 -1
  14. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  17. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  21. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  22. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  23. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  24. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  25. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  26. package/_standalone/.next/server/app/agents/page.js +1 -1
  27. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  28. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  29. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  31. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  32. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  35. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/acp/registry/route.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/agents/copy-skill/route.js +1 -0
  41. package/_standalone/.next/server/app/api/agents/copy-skill/route.js.nft.json +1 -0
  42. package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -0
  43. package/_standalone/.next/server/app/api/agents/custom/detect/route.js +1 -1
  44. package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
  45. package/_standalone/.next/server/app/api/agents/custom/route.js +1 -1
  46. package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
  47. package/_standalone/.next/server/app/api/ask/route.js +20 -9
  48. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  49. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  50. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  51. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
  55. package/_standalone/.next/server/app/api/extract-pdf/route.js +2 -2
  56. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  58. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
  59. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  60. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  61. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  62. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  63. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  64. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  65. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  66. package/_standalone/.next/server/app/api/mcp/agents/route.js +1 -1
  67. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  68. package/_standalone/.next/server/app/api/mcp/install/route.js +1 -1
  69. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  70. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  71. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  72. package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
  73. package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
  74. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  75. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  76. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  77. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  78. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  79. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  80. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  81. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  82. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  83. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  84. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  85. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  86. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  87. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  88. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  89. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  91. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  92. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  93. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  94. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/changes/page.js +2 -2
  96. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  97. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  98. package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
  99. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  100. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/echo/page.js +1 -1
  102. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  103. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  104. package/_standalone/.next/server/app/explore/page.js +1 -1
  105. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  106. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  107. package/_standalone/.next/server/app/help/page.js +1 -1
  108. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  109. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  110. package/_standalone/.next/server/app/inbox/history/page.js +1 -1
  111. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
  112. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
  113. package/_standalone/.next/server/app/login/page.js +1 -1
  114. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  115. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  116. package/_standalone/.next/server/app/page.js +1 -1
  117. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  118. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  119. package/_standalone/.next/server/app/setup/page.js +1 -1
  120. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  121. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  122. package/_standalone/.next/server/app/trash/page.js +3 -3
  123. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  124. package/_standalone/.next/server/app/view/[...path]/page.js +2 -2
  125. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  126. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  127. package/_standalone/.next/server/app/wiki/page.js +1 -1
  128. package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
  129. package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
  130. package/_standalone/.next/server/app-paths-manifest.json +23 -22
  131. package/_standalone/.next/server/chunks/1550.js +1 -1
  132. package/_standalone/.next/server/chunks/1750.js +1 -1
  133. package/_standalone/.next/server/chunks/3484.js +1 -1
  134. package/_standalone/.next/server/chunks/530.js +33 -33
  135. package/_standalone/.next/server/chunks/6539.js +1 -1
  136. package/_standalone/.next/server/chunks/{8343.js → 8955.js} +3 -3
  137. package/_standalone/.next/server/pages/500.html +2 -2
  138. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  139. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  140. package/_standalone/.next/static/5GmVArEG8OX03azKICsGq/_buildManifest.js +1 -0
  141. package/_standalone/.next/static/chunks/1369-7d0ac5d1564eed1e.js +1 -0
  142. package/_standalone/.next/static/chunks/{5581-dac72e9f16e5ea29.js → 5581-0c700c20718bd916.js} +4 -4
  143. package/_standalone/.next/static/chunks/7249-b0a9c77b9a84b11c.js +11 -0
  144. package/_standalone/.next/static/chunks/7637-904b0a381dc3ec02.js +1 -0
  145. package/_standalone/.next/static/chunks/8520-76d1b05072178b43.js +22 -0
  146. package/_standalone/.next/static/chunks/9186-ead47513192f658b.js +1 -0
  147. package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/{route-2f4705aa66819b86.js → route-2ceea6eabf25b1f2.js} +1 -1
  148. package/_standalone/.next/static/chunks/app/_global-error/{page-2f4705aa66819b86.js → page-2ceea6eabf25b1f2.js} +1 -1
  149. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-0ea3571c8fbae823.js +1 -0
  150. package/_standalone/.next/static/chunks/app/agents/{page-b172ea3743adb047.js → page-66858acbcd1d4bf8.js} +1 -1
  151. package/_standalone/.next/static/chunks/app/api/a2a/agents/{route-2f4705aa66819b86.js → route-2ceea6eabf25b1f2.js} +1 -1
  152. package/_standalone/.next/static/chunks/app/api/a2a/delegations/{route-2f4705aa66819b86.js → route-2ceea6eabf25b1f2.js} +1 -1
  153. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-2ceea6eabf25b1f2.js +1 -0
  154. package/_standalone/.next/static/chunks/app/api/a2a/route-2ceea6eabf25b1f2.js +1 -0
  155. package/_standalone/.next/static/chunks/app/api/acp/config/route-2ceea6eabf25b1f2.js +1 -0
  156. package/_standalone/.next/static/chunks/app/api/acp/detect/route-2ceea6eabf25b1f2.js +1 -0
  157. package/_standalone/.next/static/chunks/app/api/acp/install/route-2ceea6eabf25b1f2.js +1 -0
  158. package/_standalone/.next/static/chunks/app/api/acp/registry/route-2ceea6eabf25b1f2.js +1 -0
  159. package/_standalone/.next/static/chunks/app/api/acp/session/route-2ceea6eabf25b1f2.js +1 -0
  160. package/_standalone/.next/static/chunks/app/api/agent-activity/route-2ceea6eabf25b1f2.js +1 -0
  161. package/_standalone/.next/static/chunks/app/api/agents/copy-skill/route-2ceea6eabf25b1f2.js +1 -0
  162. package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-2ceea6eabf25b1f2.js +1 -0
  163. package/_standalone/.next/static/chunks/app/api/agents/custom/route-2ceea6eabf25b1f2.js +1 -0
  164. package/_standalone/.next/static/chunks/app/api/ask/route-2ceea6eabf25b1f2.js +1 -0
  165. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-2ceea6eabf25b1f2.js +1 -0
  166. package/_standalone/.next/static/chunks/app/api/auth/route-2ceea6eabf25b1f2.js +1 -0
  167. package/_standalone/.next/static/chunks/app/api/backlinks/route-2ceea6eabf25b1f2.js +1 -0
  168. package/_standalone/.next/static/chunks/app/api/bootstrap/route-2ceea6eabf25b1f2.js +1 -0
  169. package/_standalone/.next/static/chunks/app/api/changes/route-2ceea6eabf25b1f2.js +1 -0
  170. package/_standalone/.next/static/chunks/app/api/export/route-2ceea6eabf25b1f2.js +1 -0
  171. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-2ceea6eabf25b1f2.js +1 -0
  172. package/_standalone/.next/static/chunks/app/api/file/import/route-2ceea6eabf25b1f2.js +1 -0
  173. package/_standalone/.next/static/chunks/app/api/file/raw/route-2ceea6eabf25b1f2.js +1 -0
  174. package/_standalone/.next/static/chunks/app/api/file/route-2ceea6eabf25b1f2.js +1 -0
  175. package/_standalone/.next/static/chunks/app/api/files/route-2ceea6eabf25b1f2.js +1 -0
  176. package/_standalone/.next/static/chunks/app/api/git/route-2ceea6eabf25b1f2.js +1 -0
  177. package/_standalone/.next/static/chunks/app/api/graph/route-2ceea6eabf25b1f2.js +1 -0
  178. package/_standalone/.next/static/chunks/app/api/health/route-2ceea6eabf25b1f2.js +1 -0
  179. package/_standalone/.next/static/chunks/app/api/inbox/route-2ceea6eabf25b1f2.js +1 -0
  180. package/_standalone/.next/static/chunks/app/api/init/route-2ceea6eabf25b1f2.js +1 -0
  181. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-2ceea6eabf25b1f2.js +1 -0
  182. package/_standalone/.next/static/chunks/app/api/mcp/install/route-2ceea6eabf25b1f2.js +1 -0
  183. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-2ceea6eabf25b1f2.js +1 -0
  184. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-2ceea6eabf25b1f2.js +1 -0
  185. package/_standalone/.next/static/chunks/app/api/mcp/status/route-2ceea6eabf25b1f2.js +1 -0
  186. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-2ceea6eabf25b1f2.js +1 -0
  187. package/_standalone/.next/static/chunks/app/api/monitoring/route-2ceea6eabf25b1f2.js +1 -0
  188. package/_standalone/.next/static/chunks/app/api/recent-files/route-2ceea6eabf25b1f2.js +1 -0
  189. package/_standalone/.next/static/chunks/app/api/restart/route-2ceea6eabf25b1f2.js +1 -0
  190. package/_standalone/.next/static/chunks/app/api/search/route-2ceea6eabf25b1f2.js +1 -0
  191. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-2ceea6eabf25b1f2.js +1 -0
  192. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-2ceea6eabf25b1f2.js +1 -0
  193. package/_standalone/.next/static/chunks/app/api/settings/route-2ceea6eabf25b1f2.js +1 -0
  194. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-2ceea6eabf25b1f2.js +1 -0
  195. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-2ceea6eabf25b1f2.js +1 -0
  196. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-2ceea6eabf25b1f2.js +1 -0
  197. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-2ceea6eabf25b1f2.js +1 -0
  198. package/_standalone/.next/static/chunks/app/api/setup/ls/route-2ceea6eabf25b1f2.js +1 -0
  199. package/_standalone/.next/static/chunks/app/api/setup/route-2ceea6eabf25b1f2.js +1 -0
  200. package/_standalone/.next/static/chunks/app/api/skills/route-2ceea6eabf25b1f2.js +1 -0
  201. package/_standalone/.next/static/chunks/app/api/sync/route-2ceea6eabf25b1f2.js +1 -0
  202. package/_standalone/.next/static/chunks/app/api/tree-version/route-2ceea6eabf25b1f2.js +1 -0
  203. package/_standalone/.next/static/chunks/app/api/uninstall/route-2ceea6eabf25b1f2.js +1 -0
  204. package/_standalone/.next/static/chunks/app/api/update/route-2ceea6eabf25b1f2.js +1 -0
  205. package/_standalone/.next/static/chunks/app/api/update-check/route-2ceea6eabf25b1f2.js +1 -0
  206. package/_standalone/.next/static/chunks/app/api/update-status/route-2ceea6eabf25b1f2.js +1 -0
  207. package/_standalone/.next/static/chunks/app/api/workflows/route-2ceea6eabf25b1f2.js +1 -0
  208. package/_standalone/.next/static/chunks/app/changes/page-dd0b00a7b81f74e2.js +1 -0
  209. package/_standalone/.next/static/chunks/app/echo/[segment]/{page-84b95256f6e38aae.js → page-bf5c290fa3ccff09.js} +1 -1
  210. package/_standalone/.next/static/chunks/app/echo/page-2ceea6eabf25b1f2.js +1 -0
  211. package/_standalone/.next/static/chunks/app/inbox/history/{page-26e71fb6f716a4c4.js → page-3279585360df132c.js} +1 -1
  212. package/_standalone/.next/static/chunks/app/{layout-b89b0d955f39a753.js → layout-a5d5925b47e87cc3.js} +24 -24
  213. package/_standalone/.next/static/chunks/app/loading-2ceea6eabf25b1f2.js +1 -0
  214. package/_standalone/.next/static/chunks/app/{page-a8e6f085f38388bf.js → page-6a1f8d21c12b829e.js} +1 -1
  215. package/_standalone/.next/static/chunks/app/trash/page-40bc7316806acd62.js +1 -0
  216. package/_standalone/.next/static/chunks/app/view/[...path]/loading-2ceea6eabf25b1f2.js +1 -0
  217. package/_standalone/.next/static/chunks/app/view/[...path]/{page-f87f4901b5e1a88f.js → page-6fbb14b8f322d0f0.js} +1 -1
  218. package/_standalone/.next/static/chunks/app/wiki/page-ba36eccf4fe62cfe.js +1 -0
  219. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-2ceea6eabf25b1f2.js +1 -0
  220. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-2ceea6eabf25b1f2.js +1 -0
  221. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-2ceea6eabf25b1f2.js +1 -0
  222. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-2ceea6eabf25b1f2.js +1 -0
  223. package/_standalone/.next/static/css/b57c4eb3cc88308b.css +1 -0
  224. package/_standalone/.next/trace +65 -64
  225. package/_standalone/.next/types/routes.d.ts +2 -1
  226. package/_standalone/.next/types/validator.ts +9 -0
  227. package/_standalone/__tests__/api/mcp-install.test.ts +5 -2
  228. package/_standalone/components/AskFab.tsx +7 -1
  229. package/_standalone/components/FileTree.tsx +83 -1
  230. package/_standalone/components/Panel.tsx +20 -1
  231. package/_standalone/components/agents/AgentsOverviewSection.tsx +13 -11
  232. package/_standalone/components/agents/CustomAgentModal.tsx +72 -18
  233. package/_standalone/components/ask/AskContent.tsx +19 -3
  234. package/_standalone/components/ask/FileChip.tsx +93 -12
  235. package/_standalone/components/changes/ChangesBanner.tsx +1 -1
  236. package/_standalone/components/home/InboxSection.tsx +148 -32
  237. package/_standalone/components/walkthrough/WalkthroughTooltip.tsx +3 -1
  238. package/_standalone/components/walkthrough/steps.ts +1 -1
  239. package/_standalone/hooks/useAskChat.ts +10 -8
  240. package/_standalone/hooks/useFileUpload.ts +97 -43
  241. package/_standalone/hooks/useImageUpload.ts +1 -1
  242. package/_standalone/lib/inbox-upload.ts +86 -0
  243. package/_standalone/package-lock.json +2 -2
  244. package/_standalone/package.json +1 -1
  245. package/_standalone/scripts/extract-pdf.cjs +110 -3
  246. package/_standalone/tsconfig.tsbuildinfo +1 -1
  247. package/app/app/api/agents/copy-skill/route.ts +110 -0
  248. package/app/app/api/agents/custom/detect/route.ts +16 -1
  249. package/app/app/api/ask/route.ts +9 -3
  250. package/app/app/api/extract-pdf/route.ts +12 -5
  251. package/app/app/api/mcp/agents/route.ts +64 -2
  252. package/app/app/api/mcp/install/route.ts +17 -1
  253. package/app/components/AskFab.tsx +7 -1
  254. package/app/components/FileTree.tsx +83 -1
  255. package/app/components/HomeContent.tsx +14 -6
  256. package/app/components/Panel.tsx +20 -1
  257. package/app/components/agents/AgentDetailContent.tsx +58 -1
  258. package/app/components/agents/AgentsOverviewSection.tsx +13 -11
  259. package/app/components/agents/CustomAgentModal.tsx +72 -18
  260. package/app/components/ask/AskContent.tsx +19 -3
  261. package/app/components/ask/FileChip.tsx +93 -12
  262. package/app/components/changes/ChangesBanner.tsx +1 -1
  263. package/app/components/changes/ChangesContentPage.tsx +368 -168
  264. package/app/components/home/InboxSection.tsx +148 -32
  265. package/app/components/walkthrough/WalkthroughTooltip.tsx +3 -1
  266. package/app/components/walkthrough/steps.ts +1 -1
  267. package/app/hooks/useAskChat.ts +10 -8
  268. package/app/hooks/useFileUpload.ts +97 -43
  269. package/app/hooks/useImageUpload.ts +1 -1
  270. package/app/lib/acp/agent-descriptors.ts +3 -0
  271. package/app/lib/acp/subprocess.ts +56 -8
  272. package/app/lib/agent/prompt.ts +15 -4
  273. package/app/lib/custom-agents.ts +109 -1
  274. package/app/lib/file-ops.ts +58 -0
  275. package/app/lib/i18n/modules/ai-chat.ts +37 -0
  276. package/app/lib/i18n/modules/knowledge.ts +12 -0
  277. package/app/lib/inbox-upload.ts +86 -0
  278. package/app/lib/mcp-agents.ts +30 -1
  279. package/app/lib/types.ts +12 -0
  280. package/app/package.json +1 -1
  281. package/app/scripts/extract-pdf.cjs +110 -3
  282. package/bin/lib/mcp-agents.js +34 -1
  283. package/bin/lib/mcp-install.js +94 -20
  284. package/bin/lib/toml.js +125 -0
  285. package/package.json +1 -1
  286. package/scripts/build-runtime-archive.sh +5 -1
  287. package/scripts/setup.js +19 -0
  288. package/_standalone/.next/static/chunks/4237-ffc6e7c15d4007b6.js +0 -1
  289. package/_standalone/.next/static/chunks/6878-e2c5459e1c608f89.js +0 -1
  290. package/_standalone/.next/static/chunks/7249-6cf8f2b78718c59e.js +0 -11
  291. package/_standalone/.next/static/chunks/8520-56ec9ff087c15204.js +0 -22
  292. package/_standalone/.next/static/chunks/9286-5b09baa5200318c2.js +0 -1
  293. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-35ea6de1af2be3b5.js +0 -1
  294. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-2f4705aa66819b86.js +0 -1
  295. package/_standalone/.next/static/chunks/app/api/a2a/route-2f4705aa66819b86.js +0 -1
  296. package/_standalone/.next/static/chunks/app/api/acp/config/route-2f4705aa66819b86.js +0 -1
  297. package/_standalone/.next/static/chunks/app/api/acp/detect/route-2f4705aa66819b86.js +0 -1
  298. package/_standalone/.next/static/chunks/app/api/acp/install/route-2f4705aa66819b86.js +0 -1
  299. package/_standalone/.next/static/chunks/app/api/acp/registry/route-2f4705aa66819b86.js +0 -1
  300. package/_standalone/.next/static/chunks/app/api/acp/session/route-2f4705aa66819b86.js +0 -1
  301. package/_standalone/.next/static/chunks/app/api/agent-activity/route-2f4705aa66819b86.js +0 -1
  302. package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-2f4705aa66819b86.js +0 -1
  303. package/_standalone/.next/static/chunks/app/api/agents/custom/route-2f4705aa66819b86.js +0 -1
  304. package/_standalone/.next/static/chunks/app/api/ask/route-2f4705aa66819b86.js +0 -1
  305. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-2f4705aa66819b86.js +0 -1
  306. package/_standalone/.next/static/chunks/app/api/auth/route-2f4705aa66819b86.js +0 -1
  307. package/_standalone/.next/static/chunks/app/api/backlinks/route-2f4705aa66819b86.js +0 -1
  308. package/_standalone/.next/static/chunks/app/api/bootstrap/route-2f4705aa66819b86.js +0 -1
  309. package/_standalone/.next/static/chunks/app/api/changes/route-2f4705aa66819b86.js +0 -1
  310. package/_standalone/.next/static/chunks/app/api/export/route-2f4705aa66819b86.js +0 -1
  311. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-2f4705aa66819b86.js +0 -1
  312. package/_standalone/.next/static/chunks/app/api/file/import/route-2f4705aa66819b86.js +0 -1
  313. package/_standalone/.next/static/chunks/app/api/file/raw/route-2f4705aa66819b86.js +0 -1
  314. package/_standalone/.next/static/chunks/app/api/file/route-2f4705aa66819b86.js +0 -1
  315. package/_standalone/.next/static/chunks/app/api/files/route-2f4705aa66819b86.js +0 -1
  316. package/_standalone/.next/static/chunks/app/api/git/route-2f4705aa66819b86.js +0 -1
  317. package/_standalone/.next/static/chunks/app/api/graph/route-2f4705aa66819b86.js +0 -1
  318. package/_standalone/.next/static/chunks/app/api/health/route-2f4705aa66819b86.js +0 -1
  319. package/_standalone/.next/static/chunks/app/api/inbox/route-2f4705aa66819b86.js +0 -1
  320. package/_standalone/.next/static/chunks/app/api/init/route-2f4705aa66819b86.js +0 -1
  321. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-2f4705aa66819b86.js +0 -1
  322. package/_standalone/.next/static/chunks/app/api/mcp/install/route-2f4705aa66819b86.js +0 -1
  323. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-2f4705aa66819b86.js +0 -1
  324. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-2f4705aa66819b86.js +0 -1
  325. package/_standalone/.next/static/chunks/app/api/mcp/status/route-2f4705aa66819b86.js +0 -1
  326. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-2f4705aa66819b86.js +0 -1
  327. package/_standalone/.next/static/chunks/app/api/monitoring/route-2f4705aa66819b86.js +0 -1
  328. package/_standalone/.next/static/chunks/app/api/recent-files/route-2f4705aa66819b86.js +0 -1
  329. package/_standalone/.next/static/chunks/app/api/restart/route-2f4705aa66819b86.js +0 -1
  330. package/_standalone/.next/static/chunks/app/api/search/route-2f4705aa66819b86.js +0 -1
  331. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-2f4705aa66819b86.js +0 -1
  332. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-2f4705aa66819b86.js +0 -1
  333. package/_standalone/.next/static/chunks/app/api/settings/route-2f4705aa66819b86.js +0 -1
  334. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-2f4705aa66819b86.js +0 -1
  335. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-2f4705aa66819b86.js +0 -1
  336. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-2f4705aa66819b86.js +0 -1
  337. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-2f4705aa66819b86.js +0 -1
  338. package/_standalone/.next/static/chunks/app/api/setup/ls/route-2f4705aa66819b86.js +0 -1
  339. package/_standalone/.next/static/chunks/app/api/setup/route-2f4705aa66819b86.js +0 -1
  340. package/_standalone/.next/static/chunks/app/api/skills/route-2f4705aa66819b86.js +0 -1
  341. package/_standalone/.next/static/chunks/app/api/sync/route-2f4705aa66819b86.js +0 -1
  342. package/_standalone/.next/static/chunks/app/api/tree-version/route-2f4705aa66819b86.js +0 -1
  343. package/_standalone/.next/static/chunks/app/api/uninstall/route-2f4705aa66819b86.js +0 -1
  344. package/_standalone/.next/static/chunks/app/api/update/route-2f4705aa66819b86.js +0 -1
  345. package/_standalone/.next/static/chunks/app/api/update-check/route-2f4705aa66819b86.js +0 -1
  346. package/_standalone/.next/static/chunks/app/api/update-status/route-2f4705aa66819b86.js +0 -1
  347. package/_standalone/.next/static/chunks/app/api/workflows/route-2f4705aa66819b86.js +0 -1
  348. package/_standalone/.next/static/chunks/app/changes/page-6d2f49651c0061f7.js +0 -1
  349. package/_standalone/.next/static/chunks/app/echo/page-2f4705aa66819b86.js +0 -1
  350. package/_standalone/.next/static/chunks/app/loading-2f4705aa66819b86.js +0 -1
  351. package/_standalone/.next/static/chunks/app/trash/page-f92b728b78ac0f7e.js +0 -1
  352. package/_standalone/.next/static/chunks/app/view/[...path]/loading-2f4705aa66819b86.js +0 -1
  353. package/_standalone/.next/static/chunks/app/wiki/page-641edb1f3cff2f93.js +0 -1
  354. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-2f4705aa66819b86.js +0 -1
  355. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-2f4705aa66819b86.js +0 -1
  356. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-2f4705aa66819b86.js +0 -1
  357. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-2f4705aa66819b86.js +0 -1
  358. package/_standalone/.next/static/css/6c104b118d3bc9b7.css +0 -1
  359. package/_standalone/.next/static/u8p6oIRTcr_ns-ElNZ9rl/_buildManifest.js +0 -1
  360. /package/_standalone/.next/static/{u8p6oIRTcr_ns-ElNZ9rl → 5GmVArEG8OX03azKICsGq}/_ssgManifest.js +0 -0
@@ -15,7 +15,13 @@ import {
15
15
  Check,
16
16
  Clock,
17
17
  ChevronDown,
18
+ X,
19
+ ExternalLink,
20
+ Copy,
21
+ Trash2,
18
22
  } from 'lucide-react';
23
+ import { useRouter } from 'next/navigation';
24
+ import { toast } from '@/lib/toast';
19
25
  import { useLocale } from '@/lib/stores/locale-store';
20
26
  import { encodePath } from '@/lib/utils';
21
27
  import { quickDropToInbox } from '@/lib/inbox-upload';
@@ -55,6 +61,22 @@ export function InboxSection({ isOrganizing: externalOrganizing = false }: Inbox
55
61
  );
56
62
  }, [files, isOrganizing]);
57
63
 
64
+ const handleDeleteFile = useCallback(async (name: string) => {
65
+ try {
66
+ const res = await fetch('/api/inbox', {
67
+ method: 'DELETE',
68
+ headers: { 'Content-Type': 'application/json' },
69
+ body: JSON.stringify({ names: [name] }),
70
+ });
71
+ if (!res.ok) throw new Error('Failed to delete');
72
+ setFiles(prev => prev.filter(f => f.name !== name));
73
+ window.dispatchEvent(new Event('mindos:inbox-updated'));
74
+ toast.success(t.inbox.fileRemoved);
75
+ } catch {
76
+ toast.error(t.inbox.fileRemoveFailed);
77
+ }
78
+ }, [t]);
79
+
58
80
  const handleUpload = useCallback((selected: FileList | null) => {
59
81
  if (!selected || selected.length === 0) return;
60
82
  quickDropToInbox(Array.from(selected), t);
@@ -208,7 +230,7 @@ export function InboxSection({ isOrganizing: externalOrganizing = false }: Inbox
208
230
  <>
209
231
  <div className="flex flex-col gap-0.5 mb-3">
210
232
  {visibleFiles.map((file) => (
211
- <InboxFileRow key={file.path} file={file} />
233
+ <InboxFileRow key={file.path} file={file} onDelete={handleDeleteFile} />
212
234
  ))}
213
235
  </div>
214
236
  {overflowCount > 0 && (
@@ -312,45 +334,139 @@ export function InboxSection({ isOrganizing: externalOrganizing = false }: Inbox
312
334
  );
313
335
  }
314
336
 
315
- function InboxFileRow({ file }: { file: InboxFile }) {
337
+ function InboxFileRow({ file, onDelete }: { file: InboxFile; onDelete: (name: string) => void }) {
316
338
  const { t } = useLocale();
339
+ const router = useRouter();
317
340
  const isCSV = file.name.endsWith('.csv');
318
341
  const age = formatRelativeTime(file.modifiedAt, t.home.relativeTime);
342
+ const [ctxMenu, setCtxMenu] = useState<{ x: number; y: number } | null>(null);
343
+
344
+ const handleNavigate = () => {
345
+ router.push(`/view/${encodePath(file.path)}`);
346
+ };
347
+
348
+ const handleDelete = (e: React.MouseEvent) => {
349
+ e.stopPropagation();
350
+ e.preventDefault();
351
+ onDelete(file.name);
352
+ };
353
+
354
+ const handleContextMenu = (e: React.MouseEvent) => {
355
+ e.preventDefault();
356
+ e.stopPropagation();
357
+ setCtxMenu({ x: e.clientX, y: e.clientY });
358
+ };
319
359
 
320
360
  return (
321
- <Link
322
- href={`/view/${encodePath(file.path)}`}
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"
324
- >
325
- <span
326
- className={`w-1.5 h-1.5 rounded-full shrink-0 ${
327
- file.isAging ? 'bg-[var(--amber)]/60' : 'bg-[var(--amber)]'
328
- }`}
329
- />
330
- {isCSV ? (
331
- <Table size={12} className="shrink-0 text-success" />
332
- ) : (
333
- <FileText size={12} className="shrink-0 text-muted-foreground" />
334
- )}
335
- <span
336
- className="text-sm truncate flex-1 text-foreground"
337
- title={file.name}
338
- suppressHydrationWarning
361
+ <>
362
+ <div
363
+ role="button"
364
+ tabIndex={0}
365
+ onClick={handleNavigate}
366
+ onKeyDown={(e) => { if (e.key === 'Enter') handleNavigate(); }}
367
+ onContextMenu={handleContextMenu}
368
+ 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 cursor-pointer"
339
369
  >
340
- {file.name}
341
- </span>
342
- <span className="text-2xs text-muted-foreground/50 tabular-nums shrink-0">
343
- {age}
344
- </span>
345
- {file.isAging && (
346
- <span title="7+ days">
347
- <AlertCircle
348
- size={11}
349
- className="shrink-0 text-[var(--amber)]/60"
350
- />
370
+ <span
371
+ className={`w-1.5 h-1.5 rounded-full shrink-0 ${
372
+ file.isAging ? 'bg-[var(--amber)]/60' : 'bg-[var(--amber)]'
373
+ }`}
374
+ />
375
+ {isCSV ? (
376
+ <Table size={12} className="shrink-0 text-success" />
377
+ ) : (
378
+ <FileText size={12} className="shrink-0 text-muted-foreground" />
379
+ )}
380
+ <span
381
+ className="text-sm truncate flex-1 text-foreground"
382
+ title={file.name}
383
+ suppressHydrationWarning
384
+ >
385
+ {file.name}
386
+ </span>
387
+ <span className="text-2xs text-muted-foreground/50 tabular-nums shrink-0 group-hover:hidden">
388
+ {age}
351
389
  </span>
390
+ {file.isAging && (
391
+ <span title="7+ days" className="group-hover:hidden">
392
+ <AlertCircle
393
+ size={11}
394
+ className="shrink-0 text-[var(--amber)]/60"
395
+ />
396
+ </span>
397
+ )}
398
+ {/* Hover delete button */}
399
+ <button
400
+ type="button"
401
+ onClick={handleDelete}
402
+ className="hidden group-hover:flex items-center justify-center w-5 h-5 rounded shrink-0 text-muted-foreground/50 hover:text-destructive hover:bg-destructive/10 transition-colors"
403
+ title={t.inbox.removeFile}
404
+ >
405
+ <X size={12} />
406
+ </button>
407
+ </div>
408
+ {ctxMenu && (
409
+ <InboxFileContextMenu
410
+ x={ctxMenu.x}
411
+ y={ctxMenu.y}
412
+ file={file}
413
+ onDelete={() => { setCtxMenu(null); onDelete(file.name); }}
414
+ onClose={() => setCtxMenu(null)}
415
+ />
352
416
  )}
353
- </Link>
417
+ </>
418
+ );
419
+ }
420
+
421
+ /** Right-click context menu for Inbox file items */
422
+ function InboxFileContextMenu({ x, y, file, onDelete, onClose }: {
423
+ x: number; y: number; file: InboxFile; onDelete: () => void; onClose: () => void;
424
+ }) {
425
+ const menuRef = useRef<HTMLDivElement>(null);
426
+ const router = useRouter();
427
+ const { t } = useLocale();
428
+
429
+ useEffect(() => {
430
+ const handleClick = (e: MouseEvent) => {
431
+ if (menuRef.current && !menuRef.current.contains(e.target as Node)) onClose();
432
+ };
433
+ const handleKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };
434
+ document.addEventListener('mousedown', handleClick);
435
+ document.addEventListener('keydown', handleKey);
436
+ return () => { document.removeEventListener('mousedown', handleClick); document.removeEventListener('keydown', handleKey); };
437
+ }, [onClose]);
438
+
439
+ const adjX = typeof window !== 'undefined' ? Math.min(x, window.innerWidth - 200) : x;
440
+ const adjY = typeof window !== 'undefined' ? Math.min(y, window.innerHeight - 120) : y;
441
+
442
+ const menuItemClass = 'w-full flex items-center gap-2 px-3 py-1.5 text-sm text-foreground hover:bg-muted transition-colors text-left';
443
+
444
+ return (
445
+ <div
446
+ ref={menuRef}
447
+ className="fixed z-50 min-w-[160px] bg-card border border-border rounded-lg shadow-lg py-1"
448
+ style={{ top: adjY, left: adjX }}
449
+ >
450
+ <button
451
+ className={menuItemClass}
452
+ onClick={() => { router.push(`/view/${encodePath(file.path)}`); onClose(); }}
453
+ >
454
+ <ExternalLink size={14} className="shrink-0" /> {t.inbox.openFile}
455
+ </button>
456
+ <button
457
+ className={menuItemClass}
458
+ onClick={() => { navigator.clipboard.writeText(file.name); toast.copy(); onClose(); }}
459
+ >
460
+ <Copy size={14} className="shrink-0" /> {t.inbox.copyName}
461
+ </button>
462
+ <div className="border-t border-border my-1" />
463
+ <button
464
+ className={`${menuItemClass} text-destructive hover:text-destructive`}
465
+ onClick={onDelete}
466
+ >
467
+ <Trash2 size={14} className="shrink-0" /> {t.inbox.removeFile}
468
+ </button>
469
+ </div>
354
470
  );
355
471
  }
356
472
 
@@ -50,7 +50,9 @@ export default function WalkthroughTooltip({ stepIndex, rect, position }: Walkth
50
50
 
51
51
  return (
52
52
  <div
53
- className="fixed z-[102] w-[280px] rounded-xl border shadow-lg animate-in fade-in slide-in-from-left-2 duration-200"
53
+ className={`fixed z-[102] w-[280px] rounded-xl border shadow-lg animate-in fade-in duration-200 ${
54
+ position === 'right' ? 'slide-in-from-left-2' : 'slide-in-from-top-2'
55
+ }`}
54
56
  style={{
55
57
  top: `${top}px`,
56
58
  left: `${left}px`,
@@ -18,6 +18,6 @@ export interface WalkthroughStep {
18
18
  */
19
19
  export const walkthroughSteps: WalkthroughStep[] = [
20
20
  { anchor: 'files-panel', position: 'right' },
21
- { anchor: 'ask-button', position: 'right' },
21
+ { anchor: 'ask-button', position: 'bottom' },
22
22
  { anchor: 'agents-panel', position: 'right' },
23
23
  ];
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useRef, useState, useCallback } from 'react';
4
- import type { Message, ImagePart, AskMode } from '@/lib/types';
4
+ import type { Message, ImagePart, AskMode, LocalAttachment } from '@/lib/types';
5
5
  import type { ProviderId } from '@/lib/agent/providers';
6
6
  import { consumeUIMessageStream } from '@/lib/agent/stream-consumer';
7
7
  import { isRetryableError, retryDelay, sleep } from '@/lib/agent/reconnect';
@@ -18,7 +18,7 @@ export interface AskChatRefs {
18
18
  setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
19
19
  }>;
20
20
  uploadRef: React.RefObject<{
21
- localAttachments: { name: string; content: string }[];
21
+ localAttachments: LocalAttachment[];
22
22
  }>;
23
23
  selectedSkillRef: React.RefObject<{ name: string } | null>;
24
24
  selectedAcpAgentRef: React.RefObject<unknown>;
@@ -103,12 +103,14 @@ export function useAskChat({
103
103
  messages: requestMessages,
104
104
  currentFile,
105
105
  attachedFiles: refs.attachedFilesRef.current,
106
- uploadedFiles: upl.localAttachments.map(f => ({
107
- name: f.name,
108
- content: f.content.length > 20_000
109
- ? f.content.slice(0, 20_000) + '\n\n[...truncated to first ~20000 chars]'
110
- : f.content,
111
- })),
106
+ uploadedFiles: upl.localAttachments
107
+ .filter(f => f.status !== 'loading')
108
+ .map(f => ({
109
+ name: f.name,
110
+ content: f.content.length > 80_000
111
+ ? f.content.slice(0, 80_000) + '\n\n[...truncated to first ~80000 chars]'
112
+ : f.content,
113
+ })),
112
114
  selectedAcpAgent: acpAgent,
113
115
  mode: chatMode,
114
116
  providerOverride: providerOverride ?? undefined,
@@ -22,28 +22,76 @@ function uint8ToBase64(bytes: Uint8Array): string {
22
22
  return btoa(binary);
23
23
  }
24
24
 
25
- async function extractPdfText(file: File): Promise<string> {
26
- const buffer = await file.arrayBuffer();
27
- const dataBase64 = uint8ToBase64(new Uint8Array(buffer));
25
+ /**
26
+ * Extract text from a PDF file via the backend API.
27
+ * Returns a LocalAttachment with `status` reflecting the outcome.
28
+ */
29
+ async function extractPdfToAttachment(file: File): Promise<LocalAttachment> {
30
+ const name = file.name;
28
31
 
29
- const res = await fetch('/api/extract-pdf', {
30
- method: 'POST',
31
- headers: { 'Content-Type': 'application/json' },
32
- body: JSON.stringify({ name: file.name, dataBase64 }),
33
- });
34
-
35
- let payload: { text?: string; extracted?: boolean; error?: string } = {};
36
32
  try {
37
- payload = await res.json();
38
- } catch {
39
- // ignore JSON parse error
40
- }
33
+ const buffer = await file.arrayBuffer();
34
+ const dataBase64 = uint8ToBase64(new Uint8Array(buffer));
41
35
 
42
- if (!res.ok) {
43
- throw new Error(payload.error || `PDF extraction failed (${res.status})`);
44
- }
36
+ const res = await fetch('/api/extract-pdf', {
37
+ method: 'POST',
38
+ headers: { 'Content-Type': 'application/json' },
39
+ body: JSON.stringify({ name, dataBase64 }),
40
+ });
41
+
42
+ let payload: {
43
+ text?: string;
44
+ extracted?: boolean;
45
+ error?: string;
46
+ truncated?: boolean;
47
+ totalChars?: number;
48
+ pagesParsed?: number;
49
+ } = {};
50
+ try {
51
+ payload = await res.json();
52
+ } catch {
53
+ throw new Error('Failed to parse extraction response');
54
+ }
55
+
56
+ if (!res.ok) {
57
+ throw new Error(payload.error || `PDF extraction failed (${res.status})`);
58
+ }
59
+
60
+ const extracted = payload.extracted ? (payload.text || '') : '';
61
+
62
+ if (!extracted) {
63
+ return {
64
+ name,
65
+ content: `[PDF: ${name}] Could not extract readable text (possibly scanned/image PDF).`,
66
+ status: 'error',
67
+ error: 'Scanned or image-only PDF — no extractable text',
68
+ };
69
+ }
70
+
71
+ const att: LocalAttachment = {
72
+ name,
73
+ content: `[PDF TEXT EXTRACTED: ${name}]\n\n${extracted}`,
74
+ status: 'success',
75
+ };
76
+
77
+ if (payload.truncated && payload.totalChars) {
78
+ att.truncatedInfo = {
79
+ totalChars: payload.totalChars,
80
+ includedChars: extracted.length,
81
+ totalPages: payload.pagesParsed ?? 0,
82
+ };
83
+ }
45
84
 
46
- return payload.extracted ? (payload.text || '') : '';
85
+ return att;
86
+ } catch (err) {
87
+ const msg = err instanceof Error ? err.message : 'Unknown error';
88
+ return {
89
+ name,
90
+ content: `[PDF: ${name}] Failed to extract text from this PDF.`,
91
+ status: 'error',
92
+ error: msg,
93
+ };
94
+ }
47
95
  }
48
96
 
49
97
  export function useFileUpload() {
@@ -73,37 +121,43 @@ export function useFileUpload() {
73
121
  setUploadError('');
74
122
  }
75
123
 
76
- const loaded = await Promise.all(
77
- accepted.map(async (f) => {
78
- const ext = getExt(f.name);
79
- if (ext === '.pdf') {
80
- try {
81
- const extracted = await extractPdfText(f);
82
- return {
83
- name: f.name,
84
- content: extracted
85
- ? `[PDF TEXT EXTRACTED: ${f.name}]\n\n${extracted}`
86
- : `[PDF: ${f.name}] Could not extract readable text (possibly scanned/image PDF).`,
87
- };
88
- } catch {
89
- return {
90
- name: f.name,
91
- content: `[PDF: ${f.name}] Failed to extract text from this PDF.`,
92
- };
93
- }
94
- }
95
- return { name: f.name, content: await f.text() };
96
- }),
97
- );
124
+ // Phase 1: Immediately add all files — PDFs start in 'loading' state
125
+ const pdfFiles: File[] = [];
126
+ const immediateItems: LocalAttachment[] = [];
127
+
128
+ for (const f of accepted) {
129
+ if (getExt(f.name) === '.pdf') {
130
+ immediateItems.push({ name: f.name, content: '', status: 'loading' });
131
+ pdfFiles.push(f);
132
+ } else {
133
+ immediateItems.push({
134
+ name: f.name,
135
+ content: await f.text(),
136
+ status: 'success',
137
+ });
138
+ }
139
+ }
98
140
 
99
141
  setLocalAttachments((prev) => {
100
142
  const merged = [...prev];
101
- for (const item of loaded) {
102
- if (!merged.some((m) => m.name === item.name && m.content === item.content))
103
- merged.push(item);
143
+ for (const item of immediateItems) {
144
+ if (!merged.some((m) => m.name === item.name)) merged.push(item);
104
145
  }
105
146
  return merged;
106
147
  });
148
+
149
+ // Phase 2: Extract PDFs in parallel, then update each one in-place
150
+ if (pdfFiles.length > 0) {
151
+ const results = await Promise.all(pdfFiles.map(extractPdfToAttachment));
152
+
153
+ setLocalAttachments((prev) =>
154
+ prev.map((att) => {
155
+ if (att.status !== 'loading') return att;
156
+ const result = results.find((r) => r.name === att.name);
157
+ return result ?? att;
158
+ }),
159
+ );
160
+ }
107
161
  }, []);
108
162
 
109
163
  const removeAttachment = useCallback((idx: number) => {
@@ -86,7 +86,7 @@ export function useImageUpload() {
86
86
  }
87
87
  try {
88
88
  const { data, mimeType } = await compressImage(file);
89
- results.push({ type: 'image', data, mimeType });
89
+ results.push({ type: 'image', data, mimeType, fileName: file.name || undefined });
90
90
  } catch {
91
91
  setImageError(`Failed to process image: ${file.name}`);
92
92
  }
@@ -91,3 +91,89 @@ export async function quickDropToInbox(
91
91
  toast.error(t.inbox.saveFailed, 4000);
92
92
  }
93
93
  }
94
+
95
+ /**
96
+ * Drop files into a specific directory via /api/file/import.
97
+ * Used when user drags external files onto a directory in the file tree.
98
+ */
99
+ export async function quickDropToDirectory(
100
+ files: File[],
101
+ targetDir: string,
102
+ t: ReturnType<typeof useLocale>['t'],
103
+ ) {
104
+ const payload: Array<{ name: string; content: string; encoding?: string }> = [];
105
+ let oversizedCount = 0;
106
+
107
+ const BINARY_EXTS = new Set([
108
+ 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'ico',
109
+ 'mp3', 'wav', 'm4a', 'ogg', 'flac', 'aac', 'mp4', 'webm', 'mov', 'mkv',
110
+ ]);
111
+
112
+ for (const file of files) {
113
+ if (file.size > MAX_FILE_SIZE) {
114
+ oversizedCount++;
115
+ continue;
116
+ }
117
+ try {
118
+ const ext = (file.name.split('.').pop() ?? '').toLowerCase();
119
+ if (BINARY_EXTS.has(ext)) {
120
+ const buf = await file.arrayBuffer();
121
+ payload.push({ name: file.name, content: arrayBufferToBase64(buf), encoding: 'base64' });
122
+ } else {
123
+ const text = await file.text();
124
+ payload.push({ name: file.name, content: text });
125
+ }
126
+ } catch {
127
+ /* skip unreadable files */
128
+ }
129
+ }
130
+
131
+ if (payload.length === 0) {
132
+ if (oversizedCount > 0) {
133
+ toast.error(t.inbox.tooLarge(oversizedCount), 4000);
134
+ } else if (files.length > 0) {
135
+ toast.error(t.inbox.saveFailed, 4000);
136
+ }
137
+ return;
138
+ }
139
+
140
+ const dirName = targetDir.split('/').pop() || targetDir;
141
+
142
+ try {
143
+ const res = await fetch('/api/file/import', {
144
+ method: 'POST',
145
+ headers: { 'Content-Type': 'application/json' },
146
+ body: JSON.stringify({
147
+ files: payload,
148
+ targetSpace: targetDir,
149
+ organize: false,
150
+ conflict: 'rename',
151
+ }),
152
+ });
153
+
154
+ if (!res.ok) {
155
+ const data = await res.json().catch(() => ({}));
156
+ console.error('[TreeDrop] Save failed:', data.error);
157
+ toast.error(t.inbox.saveFailed, 4000);
158
+ return;
159
+ }
160
+
161
+ const result = await res.json();
162
+ const saved = result.created?.length ?? 0;
163
+ const skipped = result.skipped?.length ?? 0;
164
+
165
+ if (saved > 0 && (skipped + oversizedCount) > 0) {
166
+ toast.success(t.inbox.savedWithSkipped(saved, skipped + oversizedCount), 4000);
167
+ } else if (saved > 0) {
168
+ toast.success(t.inbox.savedToDir(saved, dirName), 3000);
169
+ } else {
170
+ if (oversizedCount > 0) toast.error(t.inbox.tooLarge(oversizedCount), 4000);
171
+ if (skipped > 0) toast.error(t.inbox.savedWithSkipped(0, skipped), 4000);
172
+ }
173
+
174
+ window.dispatchEvent(new Event('mindos:files-changed'));
175
+ } catch (err) {
176
+ console.error('[TreeDrop] Network error:', err);
177
+ toast.error(t.inbox.saveFailed, 4000);
178
+ }
179
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "wiki-app",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "wiki-app",
9
- "version": "0.1.0",
9
+ "version": "0.1.1",
10
10
  "hasInstallScript": true,
11
11
  "dependencies": {
12
12
  "@base-ui/react": "^1.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wiki-app",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "generate": "npx tsx scripts/generate-explore.ts",