@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
  }
@@ -128,6 +128,9 @@ export const AGENT_DESCRIPTORS: Record<string, AcpAgentDescriptor> = {
128
128
  'qwen-code': { binary: 'qwen-code', cmd: 'qwen-code', args: [], installCmd: 'npm install -g @qwen-code/qwen-code',
129
129
  displayName: 'Qwen Code',
130
130
  description: '阿里通义千问 Qwen 编程智能体。基于 Qwen 大模型,支持代码生成、审查和多语言编程,深度适配中文开发场景。' },
131
+ 'lingma': { binary: 'lingma', cmd: 'lingma', args: [],
132
+ displayName: 'Lingma',
133
+ description: '阿里通义灵码智能编程助手。提供代码补全、智能问答、多文件修改和编程智能体能力,支持 MCP 工具扩展。' },
131
134
  };
132
135
 
133
136
  /* ── Resolution ────────────────────────────────────────────────────────── */
@@ -27,6 +27,10 @@ export interface AcpProcess {
27
27
  agentId: string;
28
28
  proc: ChildProcess;
29
29
  alive: boolean;
30
+ /** Set when the process fails to spawn or exits with an error. */
31
+ spawnError?: string;
32
+ /** Exit code when the process has terminated. */
33
+ exitCode?: number | null;
30
34
  }
31
35
 
32
36
  type MessageCallback = (msg: AcpJsonRpcResponse) => void;
@@ -119,15 +123,18 @@ export function spawnAcpAgent(
119
123
 
120
124
  proc.on('close', (code) => {
121
125
  acpProc.alive = false;
122
- if (code && code !== 0 && stderrBuf.trim()) {
123
- console.error(`[ACP] ${entry.id} exited with code ${code}: ${stderrBuf.trim().slice(0, 500)}`);
126
+ acpProc.exitCode = code;
127
+ if (code && code !== 0) {
128
+ acpProc.spawnError = stderrBuf.trim().slice(0, 500) || `Process exited with code ${code}`;
129
+ console.error(`[ACP] ${entry.id} exited with code ${code}: ${acpProc.spawnError}`);
124
130
  }
125
- messageListeners.delete(id);
126
- requestListeners.delete(id);
131
+ // Do NOT delete listeners here — sendAndWait still needs them to reject.
132
+ // Listeners are cleaned up in killAgent() and by individual unsub calls.
127
133
  });
128
134
 
129
135
  proc.on('error', (err) => {
130
136
  acpProc.alive = false;
137
+ acpProc.spawnError = err.message;
131
138
  console.error(`[ACP] ${entry.id} spawn error:`, err.message);
132
139
  });
133
140
 
@@ -176,20 +183,61 @@ export function sendAndWait(
176
183
  timeoutMs = 30_000,
177
184
  ): Promise<AcpJsonRpcResponse> {
178
185
  return new Promise((resolve, reject) => {
179
- const rpcId = sendMessage(acpProc, method, params);
186
+ // Fail fast if process is already dead (e.g. binary not found).
187
+ if (!acpProc.alive) {
188
+ const reason = acpProc.spawnError || 'Process is not alive';
189
+ reject(new Error(
190
+ `Agent "${acpProc.agentId}" is not running: ${reason}. ` +
191
+ `Please check that the agent is installed and available on your PATH.`,
192
+ ));
193
+ return;
194
+ }
180
195
 
181
- const timer = setTimeout(() => {
196
+ let rpcId: string;
197
+ try {
198
+ rpcId = sendMessage(acpProc, method, params);
199
+ } catch (err) {
200
+ reject(err);
201
+ return;
202
+ }
203
+
204
+ const cleanup = () => {
205
+ clearTimeout(timer);
182
206
  unsub();
207
+ acpProc.proc.removeListener('close', onClose);
208
+ acpProc.proc.removeListener('error', onError);
209
+ };
210
+
211
+ const timer = setTimeout(() => {
212
+ cleanup();
183
213
  reject(new Error(`ACP RPC timeout after ${timeoutMs}ms for method: ${method}`));
184
214
  }, timeoutMs);
185
215
 
186
216
  const unsub = onMessage(acpProc, (msg) => {
187
217
  if (String(msg.id) === rpcId) {
188
- clearTimeout(timer);
189
- unsub();
218
+ cleanup();
190
219
  resolve(msg);
191
220
  }
192
221
  });
222
+
223
+ // Reject immediately if the process dies while we're waiting.
224
+ const onClose = (code: number | null) => {
225
+ cleanup();
226
+ const reason = acpProc.spawnError || `Process exited with code ${code}`;
227
+ reject(new Error(
228
+ `Agent "${acpProc.agentId}" exited unexpectedly: ${reason}. ` +
229
+ `Please check that the agent is installed and available on your PATH.`,
230
+ ));
231
+ };
232
+ const onError = (err: Error) => {
233
+ cleanup();
234
+ reject(new Error(
235
+ `Agent "${acpProc.agentId}" failed to start: ${err.message}. ` +
236
+ `Please check that the agent is installed and available on your PATH.`,
237
+ ));
238
+ };
239
+ acpProc.proc.once('close', onClose);
240
+ acpProc.proc.once('error', onError);
193
241
  });
194
242
  }
195
243
 
@@ -6,12 +6,21 @@
6
6
  * - SKILL.md owns: knowledge-base-specific execution patterns, tool selection, safety rules
7
7
  * - Tool descriptions own: per-tool usage instructions (no duplication here)
8
8
  *
9
- * Token budget: ~600 tokens (down from ~900 in v2). Freed space = more room for
10
- * SKILL.md + bootstrap context within the same context window.
9
+ * Token budget: ~750 tokens (v4 added persona warmth + self-introduction).
10
+ * Freed space = more room for SKILL.md + bootstrap context within the same context window.
11
11
  */
12
12
  export const AGENT_SYSTEM_PROMPT = `You are MindOS Agent — the operator of the user's second brain.
13
13
 
14
- Persona: Methodical, strictly objective, execution-oriented. Zero fluff. Never use preambles like "Here is the result" or "I found...".
14
+ Persona: Warm yet precise, reliable, execution-oriented. Like a trusted notebook that understands you — quiet confidence, zero fluff. Be professional but never cold; be helpful but never verbose.
15
+
16
+ ## Self-Introduction
17
+
18
+ When the user greets you ("你好", "hi", "你是谁", "what can you do", etc.) or this appears to be their first message in a new conversation, introduce yourself briefly:
19
+
20
+ - Who: MindOS Agent, the operator of their personal knowledge base (second brain).
21
+ - What: You can search, read, write, and organize their notes; capture decisions and lessons; run workflows/SOPs; and help them build a lasting, structured memory.
22
+ - Tone: Warm, concise, confident. One short paragraph, then invite them to try something — e.g., "想查点什么,还是有东西要记下来?"
23
+ - Do NOT self-introduce when the user jumps straight into a task (search, save, edit, etc.).
15
24
 
16
25
  ## Core Directives
17
26
 
@@ -45,7 +54,9 @@ Persona: Methodical, strictly objective, execution-oriented. Zero fluff. Never u
45
54
  */
46
55
  export const CHAT_SYSTEM_PROMPT = `You are MindOS Agent — the operator of the user's second brain.
47
56
 
48
- Persona: Methodical, strictly objective, execution-oriented. Zero fluff. Never use preambles like "Here is the result" or "I found...".
57
+ Persona: Warm yet precise, reliable, execution-oriented. Like a trusted notebook that understands you — quiet confidence, zero fluff. Be professional but never cold; be helpful but never verbose.
58
+
59
+ When the user greets you or asks who you are, briefly introduce yourself: you're MindOS Agent, here to help them search and read their knowledge base. Keep it warm and concise, then invite them to ask something.
49
60
 
50
61
  ## Mode: Chat (Read-Only)
51
62