@geminilight/mindos 0.6.67 → 0.6.70

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 (500) 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 +26 -25
  4. package/_standalone/.next/build-manifest.json +3 -3
  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/react-loadable-manifest.json +7 -7
  10. package/_standalone/.next/routes-manifest.json +6 -0
  11. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  12. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  13. package/_standalone/.next/server/app/_global-error.html +2 -2
  14. package/_standalone/.next/server/app/_global-error.rsc +1 -1
  15. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  16. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  17. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  18. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  19. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  21. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  22. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  23. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  24. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  25. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  26. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  27. package/_standalone/.next/server/app/agents/page.js +1 -1
  28. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  29. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  31. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  32. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  35. package/_standalone/.next/server/app/api/acp/detect/route.js +1 -1
  36. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/acp/registry/route.js +1 -1
  39. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/acp/session/route.js +1 -1
  41. package/_standalone/.next/server/app/api/acp/session/route.js.nft.json +1 -1
  42. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  43. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  44. package/_standalone/.next/server/app/api/agents/copy-skill/route.js.nft.json +1 -1
  45. package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -1
  46. package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
  47. package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
  48. package/_standalone/.next/server/app/api/ask/route.js +17 -17
  49. package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
  50. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  51. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  53. package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
  54. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  55. package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
  56. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
  58. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  59. package/_standalone/.next/server/app/api/channels/verify/route.js +1 -0
  60. package/_standalone/.next/server/app/api/channels/verify/route.js.nft.json +1 -0
  61. package/_standalone/.next/server/app/api/channels/verify/route_client-reference-manifest.js +1 -0
  62. package/_standalone/.next/server/app/api/connect/route_client-reference-manifest.js +1 -1
  63. package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
  64. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  65. package/_standalone/.next/server/app/api/extract-pdf/route.js +2 -2
  66. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  67. package/_standalone/.next/server/app/api/file/import/route.js +1 -1
  68. package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
  69. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  70. package/_standalone/.next/server/app/api/file/raw/route.js.nft.json +1 -1
  71. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
  72. package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
  73. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  74. package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  75. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  76. package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  77. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  78. package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
  79. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  80. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  81. package/_standalone/.next/server/app/api/im/config/route_client-reference-manifest.js +1 -1
  82. package/_standalone/.next/server/app/api/im/status/route_client-reference-manifest.js +1 -1
  83. package/_standalone/.next/server/app/api/im/test/route_client-reference-manifest.js +1 -1
  84. package/_standalone/.next/server/app/api/inbox/clip/route.js.nft.json +1 -1
  85. package/_standalone/.next/server/app/api/inbox/clip/route_client-reference-manifest.js +1 -1
  86. package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
  87. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  88. package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
  89. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/lint/route.js.nft.json +1 -1
  91. package/_standalone/.next/server/app/api/lint/route_client-reference-manifest.js +1 -1
  92. package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
  93. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  94. package/_standalone/.next/server/app/api/mcp/direct-tools/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  96. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  97. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  98. package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
  99. package/_standalone/.next/server/app/api/mcp/tools/route_client-reference-manifest.js +1 -1
  100. package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
  102. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  103. package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
  104. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  105. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  106. package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  107. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  108. package/_standalone/.next/server/app/api/settings/list-models/route.js +1 -1
  109. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  110. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  111. package/_standalone/.next/server/app/api/settings/route.js +1 -1
  112. package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  113. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  114. package/_standalone/.next/server/app/api/settings/test-key/route.js +1 -1
  115. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  116. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  117. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  118. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  119. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  120. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  121. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  122. package/_standalone/.next/server/app/api/space-overview/route.js +2 -2
  123. package/_standalone/.next/server/app/api/space-overview/route.js.nft.json +1 -1
  124. package/_standalone/.next/server/app/api/space-overview/route_client-reference-manifest.js +1 -1
  125. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  126. package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
  127. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  128. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  129. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  130. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  131. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  132. package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
  133. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  134. package/_standalone/.next/server/app/changelog/page.js +1 -1
  135. package/_standalone/.next/server/app/changelog/page.js.nft.json +1 -1
  136. package/_standalone/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  137. package/_standalone/.next/server/app/changes/page.js +1 -1
  138. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  139. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  140. package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
  141. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  142. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  143. package/_standalone/.next/server/app/echo/page.js +1 -1
  144. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  145. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  146. package/_standalone/.next/server/app/explore/page.js +1 -1
  147. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  148. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  149. package/_standalone/.next/server/app/help/page.js +1 -1
  150. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  151. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  152. package/_standalone/.next/server/app/inbox/history/page.js +1 -1
  153. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
  154. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
  155. package/_standalone/.next/server/app/login/page.js +1 -1
  156. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  157. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  158. package/_standalone/.next/server/app/page.js +1 -1
  159. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  160. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  161. package/_standalone/.next/server/app/setup/page.js +1 -1
  162. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  163. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  164. package/_standalone/.next/server/app/trash/page.js +3 -3
  165. package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
  166. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  167. package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
  168. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  169. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  170. package/_standalone/.next/server/app/wiki/page.js +1 -1
  171. package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
  172. package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
  173. package/_standalone/.next/server/app-paths-manifest.json +26 -25
  174. package/_standalone/.next/server/chunks/3437.js +2 -2
  175. package/_standalone/.next/server/chunks/5299.js +1 -0
  176. package/_standalone/.next/server/chunks/6022.js +39 -39
  177. package/_standalone/.next/server/chunks/6133.js +54 -0
  178. package/_standalone/.next/server/chunks/6539.js +1 -1
  179. package/_standalone/.next/server/chunks/8326.js +1 -0
  180. package/_standalone/.next/server/chunks/8388.js +5 -3
  181. package/_standalone/.next/server/chunks/953.js +6 -4
  182. package/_standalone/.next/server/chunks/9938.js +24 -0
  183. package/_standalone/.next/server/middleware-build-manifest.js +1 -1
  184. package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  185. package/_standalone/.next/server/pages/500.html +2 -2
  186. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  187. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  188. package/_standalone/.next/static/chunks/1814.8a1fef15856dce84.js +1 -0
  189. package/_standalone/.next/static/chunks/2654-e07c692d6c99f25b.js +1 -0
  190. package/_standalone/.next/static/chunks/{2935.7d75923daaf448d3.js → 2935.9b08eeade3644806.js} +1 -1
  191. package/_standalone/.next/static/chunks/3269.a7343771e3f0ff58.js +48 -0
  192. package/_standalone/.next/static/chunks/3637.2b2697198968d83f.js +1 -0
  193. package/_standalone/.next/static/chunks/{5550-b7c97fc13628db15.js → 4327-d70a8d457e2d03fe.js} +1 -1
  194. package/_standalone/.next/static/chunks/48-c88ea6a2a45f15b4.js +28 -0
  195. package/_standalone/.next/static/chunks/5581-6d403608b5dfb20b.js +29 -0
  196. package/_standalone/.next/static/chunks/6902-edc5c487c696bd0b.js +3 -0
  197. package/_standalone/.next/static/chunks/808.72eb7bdd399e9a24.js +1 -0
  198. package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/{route-e0c1e2c67572781c.js → route-930dfa67e2789df5.js} +1 -1
  199. package/_standalone/.next/static/chunks/app/_global-error/{page-e0c1e2c67572781c.js → page-930dfa67e2789df5.js} +1 -1
  200. package/_standalone/.next/static/chunks/app/agents/page-3dc2bf2f6bc7334c.js +1 -0
  201. package/_standalone/.next/static/chunks/app/api/a2a/agents/{route-e0c1e2c67572781c.js → route-930dfa67e2789df5.js} +1 -1
  202. package/_standalone/.next/static/chunks/app/api/a2a/delegations/{route-e0c1e2c67572781c.js → route-930dfa67e2789df5.js} +1 -1
  203. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-930dfa67e2789df5.js +1 -0
  204. package/_standalone/.next/static/chunks/app/api/a2a/route-930dfa67e2789df5.js +1 -0
  205. package/_standalone/.next/static/chunks/app/api/acp/config/route-930dfa67e2789df5.js +1 -0
  206. package/_standalone/.next/static/chunks/app/api/acp/detect/route-930dfa67e2789df5.js +1 -0
  207. package/_standalone/.next/static/chunks/app/api/acp/install/route-930dfa67e2789df5.js +1 -0
  208. package/_standalone/.next/static/chunks/app/api/acp/registry/route-930dfa67e2789df5.js +1 -0
  209. package/_standalone/.next/static/chunks/app/api/acp/session/route-930dfa67e2789df5.js +1 -0
  210. package/_standalone/.next/static/chunks/app/api/agent-activity/route-930dfa67e2789df5.js +1 -0
  211. package/_standalone/.next/static/chunks/app/api/agents/copy-skill/route-930dfa67e2789df5.js +1 -0
  212. package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-930dfa67e2789df5.js +1 -0
  213. package/_standalone/.next/static/chunks/app/api/agents/custom/route-930dfa67e2789df5.js +1 -0
  214. package/_standalone/.next/static/chunks/app/api/ask/route-930dfa67e2789df5.js +1 -0
  215. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-930dfa67e2789df5.js +1 -0
  216. package/_standalone/.next/static/chunks/app/api/auth/route-930dfa67e2789df5.js +1 -0
  217. package/_standalone/.next/static/chunks/app/api/backlinks/route-930dfa67e2789df5.js +1 -0
  218. package/_standalone/.next/static/chunks/app/api/bootstrap/route-930dfa67e2789df5.js +1 -0
  219. package/_standalone/.next/static/chunks/app/api/changes/route-930dfa67e2789df5.js +1 -0
  220. package/_standalone/.next/static/chunks/app/api/channels/verify/route-930dfa67e2789df5.js +1 -0
  221. package/_standalone/.next/static/chunks/app/api/connect/route-930dfa67e2789df5.js +1 -0
  222. package/_standalone/.next/static/chunks/app/api/export/route-930dfa67e2789df5.js +1 -0
  223. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-930dfa67e2789df5.js +1 -0
  224. package/_standalone/.next/static/chunks/app/api/file/import/route-930dfa67e2789df5.js +1 -0
  225. package/_standalone/.next/static/chunks/app/api/file/raw/route-930dfa67e2789df5.js +1 -0
  226. package/_standalone/.next/static/chunks/app/api/file/route-930dfa67e2789df5.js +1 -0
  227. package/_standalone/.next/static/chunks/app/api/files/route-930dfa67e2789df5.js +1 -0
  228. package/_standalone/.next/static/chunks/app/api/git/route-930dfa67e2789df5.js +1 -0
  229. package/_standalone/.next/static/chunks/app/api/graph/route-930dfa67e2789df5.js +1 -0
  230. package/_standalone/.next/static/chunks/app/api/health/route-930dfa67e2789df5.js +1 -0
  231. package/_standalone/.next/static/chunks/app/api/im/config/route-930dfa67e2789df5.js +1 -0
  232. package/_standalone/.next/static/chunks/app/api/im/status/route-930dfa67e2789df5.js +1 -0
  233. package/_standalone/.next/static/chunks/app/api/im/test/route-930dfa67e2789df5.js +1 -0
  234. package/_standalone/.next/static/chunks/app/api/inbox/clip/route-930dfa67e2789df5.js +1 -0
  235. package/_standalone/.next/static/chunks/app/api/inbox/route-930dfa67e2789df5.js +1 -0
  236. package/_standalone/.next/static/chunks/app/api/init/route-930dfa67e2789df5.js +1 -0
  237. package/_standalone/.next/static/chunks/app/api/lint/route-930dfa67e2789df5.js +1 -0
  238. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-930dfa67e2789df5.js +1 -0
  239. package/_standalone/.next/static/chunks/app/api/mcp/direct-tools/route-930dfa67e2789df5.js +1 -0
  240. package/_standalone/.next/static/chunks/app/api/mcp/install/route-930dfa67e2789df5.js +1 -0
  241. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-930dfa67e2789df5.js +1 -0
  242. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-930dfa67e2789df5.js +1 -0
  243. package/_standalone/.next/static/chunks/app/api/mcp/status/route-930dfa67e2789df5.js +1 -0
  244. package/_standalone/.next/static/chunks/app/api/mcp/tools/route-930dfa67e2789df5.js +1 -0
  245. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-930dfa67e2789df5.js +1 -0
  246. package/_standalone/.next/static/chunks/app/api/monitoring/route-930dfa67e2789df5.js +1 -0
  247. package/_standalone/.next/static/chunks/app/api/recent-files/route-930dfa67e2789df5.js +1 -0
  248. package/_standalone/.next/static/chunks/app/api/restart/route-930dfa67e2789df5.js +1 -0
  249. package/_standalone/.next/static/chunks/app/api/search/route-930dfa67e2789df5.js +1 -0
  250. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-930dfa67e2789df5.js +1 -0
  251. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-930dfa67e2789df5.js +1 -0
  252. package/_standalone/.next/static/chunks/app/api/settings/route-930dfa67e2789df5.js +1 -0
  253. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-930dfa67e2789df5.js +1 -0
  254. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-930dfa67e2789df5.js +1 -0
  255. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-930dfa67e2789df5.js +1 -0
  256. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-930dfa67e2789df5.js +1 -0
  257. package/_standalone/.next/static/chunks/app/api/setup/ls/route-930dfa67e2789df5.js +1 -0
  258. package/_standalone/.next/static/chunks/app/api/setup/route-930dfa67e2789df5.js +1 -0
  259. package/_standalone/.next/static/chunks/app/api/skills/route-930dfa67e2789df5.js +1 -0
  260. package/_standalone/.next/static/chunks/app/api/space-overview/route-930dfa67e2789df5.js +1 -0
  261. package/_standalone/.next/static/chunks/app/api/sync/route-930dfa67e2789df5.js +1 -0
  262. package/_standalone/.next/static/chunks/app/api/tree-version/route-930dfa67e2789df5.js +1 -0
  263. package/_standalone/.next/static/chunks/app/api/uninstall/route-930dfa67e2789df5.js +1 -0
  264. package/_standalone/.next/static/chunks/app/api/update/route-930dfa67e2789df5.js +1 -0
  265. package/_standalone/.next/static/chunks/app/api/update-check/route-930dfa67e2789df5.js +1 -0
  266. package/_standalone/.next/static/chunks/app/api/update-status/route-930dfa67e2789df5.js +1 -0
  267. package/_standalone/.next/static/chunks/app/api/workflows/route-930dfa67e2789df5.js +1 -0
  268. package/_standalone/.next/static/chunks/app/changes/page-930dfa67e2789df5.js +1 -0
  269. package/_standalone/.next/static/chunks/app/echo/[segment]/page-75a6330292613587.js +157 -0
  270. package/_standalone/.next/static/chunks/app/echo/page-930dfa67e2789df5.js +1 -0
  271. package/_standalone/.next/static/chunks/app/{layout-9bb19a959ffb87ac.js → layout-8aa53b34ef34a246.js} +28 -28
  272. package/_standalone/.next/static/chunks/app/loading-930dfa67e2789df5.js +1 -0
  273. package/_standalone/.next/static/chunks/app/{page-c3be6477dbcf182d.js → page-318332501426ef5b.js} +1 -1
  274. package/_standalone/.next/static/chunks/app/trash/page-17bd5aedcfea9b65.js +1 -0
  275. package/_standalone/.next/static/chunks/app/view/[...path]/loading-930dfa67e2789df5.js +1 -0
  276. package/_standalone/.next/static/chunks/app/view/[...path]/page-d5c37c41c556013d.js +12 -0
  277. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-930dfa67e2789df5.js +1 -0
  278. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-930dfa67e2789df5.js +1 -0
  279. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-930dfa67e2789df5.js +1 -0
  280. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-930dfa67e2789df5.js +1 -0
  281. package/_standalone/.next/static/chunks/webpack-1c2d44f6d86f3986.js +1 -0
  282. package/_standalone/.next/static/css/a8cadde78aea8585.css +1 -0
  283. package/_standalone/.next/static/ixCTELNH6V05Z00pC6ZMO/_buildManifest.js +1 -0
  284. package/_standalone/.next/trace +72 -71
  285. package/_standalone/.next/types/routes.d.ts +2 -1
  286. package/_standalone/.next/types/validator.ts +9 -0
  287. package/_standalone/MINDOS_ARCHITECTURE_DIAGRAM.md +488 -0
  288. package/_standalone/MINDOS_EXPLORATION_SUMMARY.md +229 -0
  289. package/_standalone/MINDOS_INFRASTRUCTURE_ANALYSIS.md +732 -0
  290. package/_standalone/__tests__/acp/agent-descriptors.test.ts +101 -3
  291. package/_standalone/__tests__/acp/registry.test.ts +34 -5
  292. package/_standalone/__tests__/acp/session.test.ts +346 -167
  293. package/_standalone/__tests__/agent/provider-endpoints.test.ts +70 -0
  294. package/_standalone/__tests__/api/channels-verify.test.ts +75 -0
  295. package/_standalone/__tests__/api/extract-pdf.test.ts +265 -0
  296. package/_standalone/__tests__/api/test-key.test.ts +15 -3
  297. package/_standalone/__tests__/channel-mgmt.test.js +11 -0
  298. package/_standalone/__tests__/components/breadcrumb-header-ux.test.ts +14 -0
  299. package/_standalone/__tests__/components/header-toc-vertical-alignment.test.ts +23 -0
  300. package/_standalone/__tests__/components/table-of-contents-header-layout.test.ts +15 -0
  301. package/_standalone/__tests__/components/view-page-header-layout.test.ts +13 -0
  302. package/_standalone/__tests__/components/view-page-header-scroll-stability.test.ts +34 -0
  303. package/_standalone/__tests__/core/hybrid-search.test.ts +109 -0
  304. package/_standalone/components/Breadcrumb.tsx +10 -10
  305. package/_standalone/components/FindInPage.tsx +1 -1
  306. package/_standalone/components/MarkdownView.tsx +4 -0
  307. package/_standalone/components/Panel.tsx +17 -10
  308. package/_standalone/components/TableOfContents.tsx +9 -9
  309. package/_standalone/components/agents/AgentsContentChannelDetail.tsx +168 -54
  310. package/_standalone/components/agents/AgentsContentChannels.tsx +22 -22
  311. package/_standalone/components/ask/AskContent.tsx +68 -28
  312. package/_standalone/components/ask/AskHeader.tsx +6 -2
  313. package/_standalone/components/ask/ProviderModelCapsule.tsx +11 -9
  314. package/_standalone/components/ask/SessionHistoryPanel.tsx +398 -0
  315. package/_standalone/components/panels/AgentsPanel.tsx +8 -1
  316. package/_standalone/components/settings/AiTab.tsx +5 -1
  317. package/_standalone/components/settings/KnowledgeTab.tsx +92 -1
  318. package/_standalone/components/settings/McpConnectGuides.tsx +4 -0
  319. package/_standalone/components/settings/McpPortSection.tsx +207 -0
  320. package/_standalone/components/settings/McpTab.tsx +1 -5
  321. package/_standalone/components/settings/TestButton.tsx +1 -0
  322. package/_standalone/components/settings/{ServerPortsCard.tsx → WebPortSection.tsx} +66 -151
  323. package/_standalone/components/settings/types.ts +12 -0
  324. package/_standalone/components/settings/useCustomProviderForm.ts +2 -2
  325. package/_standalone/data/skills/mindos/SKILL.md +45 -1
  326. package/_standalone/hooks/useAcpDetection.ts +1 -1
  327. package/_standalone/hooks/useAcpRegistry.ts +1 -1
  328. package/_standalone/hooks/useFileImport.ts +7 -2
  329. package/_standalone/hooks/useFileUpload.ts +17 -10
  330. package/_standalone/lib/acp/index.ts +4 -6
  331. package/_standalone/lib/acp/types.ts +0 -29
  332. package/_standalone/lib/im/platforms.ts +6 -2
  333. package/_standalone/lib/pdf-extract.ts +6 -2
  334. package/_standalone/package-lock.json +12 -2
  335. package/_standalone/package.json +2 -1
  336. package/_standalone/tsconfig.tsbuildinfo +1 -1
  337. package/app/MINDOS_ARCHITECTURE_DIAGRAM.md +488 -0
  338. package/app/MINDOS_EXPLORATION_SUMMARY.md +229 -0
  339. package/app/MINDOS_INFRASTRUCTURE_ANALYSIS.md +732 -0
  340. package/app/app/api/acp/detect/route.ts +9 -15
  341. package/app/app/api/channels/verify/route.ts +54 -0
  342. package/app/app/api/extract-pdf/route.ts +17 -3
  343. package/app/app/api/settings/list-models/route.ts +40 -44
  344. package/app/app/api/settings/route.ts +16 -0
  345. package/app/app/api/settings/test-key/route.ts +5 -2
  346. package/app/app/view/[...path]/ViewPageClient.tsx +1 -1
  347. package/app/components/Breadcrumb.tsx +10 -10
  348. package/app/components/DirView.tsx +1 -1
  349. package/app/components/FindInPage.tsx +1 -1
  350. package/app/components/InboxView.tsx +2 -2
  351. package/app/components/MarkdownView.tsx +4 -0
  352. package/app/components/Panel.tsx +17 -10
  353. package/app/components/TableOfContents.tsx +9 -9
  354. package/app/components/agents/AgentsContentChannelDetail.tsx +168 -54
  355. package/app/components/agents/AgentsContentChannels.tsx +22 -22
  356. package/app/components/ask/AskContent.tsx +68 -28
  357. package/app/components/ask/AskHeader.tsx +6 -2
  358. package/app/components/ask/ProviderModelCapsule.tsx +11 -9
  359. package/app/components/ask/SessionHistoryPanel.tsx +398 -0
  360. package/app/components/panels/AgentsPanel.tsx +8 -1
  361. package/app/components/settings/AiTab.tsx +5 -1
  362. package/app/components/settings/KnowledgeTab.tsx +92 -1
  363. package/app/components/settings/McpConnectGuides.tsx +4 -0
  364. package/app/components/settings/McpPortSection.tsx +207 -0
  365. package/app/components/settings/McpTab.tsx +1 -5
  366. package/app/components/settings/TestButton.tsx +1 -0
  367. package/app/components/settings/{ServerPortsCard.tsx → WebPortSection.tsx} +66 -151
  368. package/app/components/settings/types.ts +12 -0
  369. package/app/components/settings/useCustomProviderForm.ts +2 -2
  370. package/app/data/skills/mindos/SKILL.md +45 -1
  371. package/app/hooks/useAcpDetection.ts +1 -1
  372. package/app/hooks/useAcpRegistry.ts +1 -1
  373. package/app/hooks/useFileImport.ts +7 -2
  374. package/app/hooks/useFileUpload.ts +17 -10
  375. package/app/lib/acp/agent-descriptors.ts +69 -29
  376. package/app/lib/acp/index.ts +4 -6
  377. package/app/lib/acp/registry.ts +43 -47
  378. package/app/lib/acp/session.ts +253 -517
  379. package/app/lib/acp/subprocess.ts +249 -414
  380. package/app/lib/acp/types.ts +0 -29
  381. package/app/lib/agent/model.ts +20 -4
  382. package/app/lib/agent/non-streaming.ts +37 -20
  383. package/app/lib/agent/providers.ts +31 -0
  384. package/app/lib/agent/tools.ts +5 -3
  385. package/app/lib/core/embedding-index.ts +285 -0
  386. package/app/lib/core/embedding-provider.ts +164 -0
  387. package/app/lib/core/hybrid-search.ts +160 -0
  388. package/app/lib/core/search.ts +11 -21
  389. package/app/lib/i18n/modules/ai-chat.ts +26 -0
  390. package/app/lib/i18n/modules/panels.ts +14 -0
  391. package/app/lib/i18n/modules/settings.ts +2 -0
  392. package/app/lib/im/platforms.ts +6 -2
  393. package/app/lib/im/verify.ts +94 -0
  394. package/app/lib/pdf-extract.ts +6 -2
  395. package/app/lib/settings.ts +23 -0
  396. package/app/package.json +2 -1
  397. package/bin/cli.js +3 -1
  398. package/bin/commands/channel.js +342 -0
  399. package/bin/commands/update.js +11 -4
  400. package/bin/lib/build.js +34 -16
  401. package/bin/lib/channel-config.js +168 -0
  402. package/bin/lib/channel-constants.js +88 -0
  403. package/bin/lib/channel-mgmt.js +244 -0
  404. package/bin/lib/channel-prompts.js +72 -0
  405. package/bin/lib/channel-validate.js +57 -0
  406. package/bin/lib/safe-rm.js +165 -0
  407. package/package.json +1 -1
  408. package/skills/mindos/SKILL.md +45 -1
  409. package/_standalone/.next/server/chunks/1750.js +0 -1
  410. package/_standalone/.next/server/chunks/8947.js +0 -52
  411. package/_standalone/.next/static/0JtsgqDZLSJ6MrIZIV6gC/_buildManifest.js +0 -1
  412. package/_standalone/.next/static/chunks/1814.a79b84d37df75c43.js +0 -1
  413. package/_standalone/.next/static/chunks/3637.38c4f28d8f698e0e.js +0 -1
  414. package/_standalone/.next/static/chunks/4351-9ab695985bb808ad.js +0 -1
  415. package/_standalone/.next/static/chunks/476.463546c195b89cce.js +0 -48
  416. package/_standalone/.next/static/chunks/5133-3779d65f4fdfb041.js +0 -30
  417. package/_standalone/.next/static/chunks/5581-4dd3d32f6e8606ec.js +0 -29
  418. package/_standalone/.next/static/chunks/5998.7bd28de9747440b5.js +0 -1
  419. package/_standalone/.next/static/chunks/app/agents/page-4c0637183e46c8d3.js +0 -1
  420. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-e0c1e2c67572781c.js +0 -1
  421. package/_standalone/.next/static/chunks/app/api/a2a/route-e0c1e2c67572781c.js +0 -1
  422. package/_standalone/.next/static/chunks/app/api/acp/config/route-e0c1e2c67572781c.js +0 -1
  423. package/_standalone/.next/static/chunks/app/api/acp/detect/route-e0c1e2c67572781c.js +0 -1
  424. package/_standalone/.next/static/chunks/app/api/acp/install/route-e0c1e2c67572781c.js +0 -1
  425. package/_standalone/.next/static/chunks/app/api/acp/registry/route-e0c1e2c67572781c.js +0 -1
  426. package/_standalone/.next/static/chunks/app/api/acp/session/route-e0c1e2c67572781c.js +0 -1
  427. package/_standalone/.next/static/chunks/app/api/agent-activity/route-e0c1e2c67572781c.js +0 -1
  428. package/_standalone/.next/static/chunks/app/api/agents/copy-skill/route-e0c1e2c67572781c.js +0 -1
  429. package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-e0c1e2c67572781c.js +0 -1
  430. package/_standalone/.next/static/chunks/app/api/agents/custom/route-e0c1e2c67572781c.js +0 -1
  431. package/_standalone/.next/static/chunks/app/api/ask/route-e0c1e2c67572781c.js +0 -1
  432. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-e0c1e2c67572781c.js +0 -1
  433. package/_standalone/.next/static/chunks/app/api/auth/route-e0c1e2c67572781c.js +0 -1
  434. package/_standalone/.next/static/chunks/app/api/backlinks/route-e0c1e2c67572781c.js +0 -1
  435. package/_standalone/.next/static/chunks/app/api/bootstrap/route-e0c1e2c67572781c.js +0 -1
  436. package/_standalone/.next/static/chunks/app/api/changes/route-e0c1e2c67572781c.js +0 -1
  437. package/_standalone/.next/static/chunks/app/api/connect/route-e0c1e2c67572781c.js +0 -1
  438. package/_standalone/.next/static/chunks/app/api/export/route-e0c1e2c67572781c.js +0 -1
  439. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-e0c1e2c67572781c.js +0 -1
  440. package/_standalone/.next/static/chunks/app/api/file/import/route-e0c1e2c67572781c.js +0 -1
  441. package/_standalone/.next/static/chunks/app/api/file/raw/route-e0c1e2c67572781c.js +0 -1
  442. package/_standalone/.next/static/chunks/app/api/file/route-e0c1e2c67572781c.js +0 -1
  443. package/_standalone/.next/static/chunks/app/api/files/route-e0c1e2c67572781c.js +0 -1
  444. package/_standalone/.next/static/chunks/app/api/git/route-e0c1e2c67572781c.js +0 -1
  445. package/_standalone/.next/static/chunks/app/api/graph/route-e0c1e2c67572781c.js +0 -1
  446. package/_standalone/.next/static/chunks/app/api/health/route-e0c1e2c67572781c.js +0 -1
  447. package/_standalone/.next/static/chunks/app/api/im/config/route-e0c1e2c67572781c.js +0 -1
  448. package/_standalone/.next/static/chunks/app/api/im/status/route-e0c1e2c67572781c.js +0 -1
  449. package/_standalone/.next/static/chunks/app/api/im/test/route-e0c1e2c67572781c.js +0 -1
  450. package/_standalone/.next/static/chunks/app/api/inbox/clip/route-e0c1e2c67572781c.js +0 -1
  451. package/_standalone/.next/static/chunks/app/api/inbox/route-e0c1e2c67572781c.js +0 -1
  452. package/_standalone/.next/static/chunks/app/api/init/route-e0c1e2c67572781c.js +0 -1
  453. package/_standalone/.next/static/chunks/app/api/lint/route-e0c1e2c67572781c.js +0 -1
  454. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-e0c1e2c67572781c.js +0 -1
  455. package/_standalone/.next/static/chunks/app/api/mcp/direct-tools/route-e0c1e2c67572781c.js +0 -1
  456. package/_standalone/.next/static/chunks/app/api/mcp/install/route-e0c1e2c67572781c.js +0 -1
  457. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-e0c1e2c67572781c.js +0 -1
  458. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-e0c1e2c67572781c.js +0 -1
  459. package/_standalone/.next/static/chunks/app/api/mcp/status/route-e0c1e2c67572781c.js +0 -1
  460. package/_standalone/.next/static/chunks/app/api/mcp/tools/route-e0c1e2c67572781c.js +0 -1
  461. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-e0c1e2c67572781c.js +0 -1
  462. package/_standalone/.next/static/chunks/app/api/monitoring/route-e0c1e2c67572781c.js +0 -1
  463. package/_standalone/.next/static/chunks/app/api/recent-files/route-e0c1e2c67572781c.js +0 -1
  464. package/_standalone/.next/static/chunks/app/api/restart/route-e0c1e2c67572781c.js +0 -1
  465. package/_standalone/.next/static/chunks/app/api/search/route-e0c1e2c67572781c.js +0 -1
  466. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-e0c1e2c67572781c.js +0 -1
  467. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-e0c1e2c67572781c.js +0 -1
  468. package/_standalone/.next/static/chunks/app/api/settings/route-e0c1e2c67572781c.js +0 -1
  469. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-e0c1e2c67572781c.js +0 -1
  470. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-e0c1e2c67572781c.js +0 -1
  471. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-e0c1e2c67572781c.js +0 -1
  472. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-e0c1e2c67572781c.js +0 -1
  473. package/_standalone/.next/static/chunks/app/api/setup/ls/route-e0c1e2c67572781c.js +0 -1
  474. package/_standalone/.next/static/chunks/app/api/setup/route-e0c1e2c67572781c.js +0 -1
  475. package/_standalone/.next/static/chunks/app/api/skills/route-e0c1e2c67572781c.js +0 -1
  476. package/_standalone/.next/static/chunks/app/api/space-overview/route-e0c1e2c67572781c.js +0 -1
  477. package/_standalone/.next/static/chunks/app/api/sync/route-e0c1e2c67572781c.js +0 -1
  478. package/_standalone/.next/static/chunks/app/api/tree-version/route-e0c1e2c67572781c.js +0 -1
  479. package/_standalone/.next/static/chunks/app/api/uninstall/route-e0c1e2c67572781c.js +0 -1
  480. package/_standalone/.next/static/chunks/app/api/update/route-e0c1e2c67572781c.js +0 -1
  481. package/_standalone/.next/static/chunks/app/api/update-check/route-e0c1e2c67572781c.js +0 -1
  482. package/_standalone/.next/static/chunks/app/api/update-status/route-e0c1e2c67572781c.js +0 -1
  483. package/_standalone/.next/static/chunks/app/api/workflows/route-e0c1e2c67572781c.js +0 -1
  484. package/_standalone/.next/static/chunks/app/changes/page-e0c1e2c67572781c.js +0 -1
  485. package/_standalone/.next/static/chunks/app/echo/[segment]/page-5333ab47257fab7f.js +0 -159
  486. package/_standalone/.next/static/chunks/app/echo/page-e0c1e2c67572781c.js +0 -1
  487. package/_standalone/.next/static/chunks/app/loading-e0c1e2c67572781c.js +0 -1
  488. package/_standalone/.next/static/chunks/app/trash/page-bebb28bf472cf691.js +0 -1
  489. package/_standalone/.next/static/chunks/app/view/[...path]/loading-e0c1e2c67572781c.js +0 -1
  490. package/_standalone/.next/static/chunks/app/view/[...path]/page-dd5698f3df138835.js +0 -12
  491. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-e0c1e2c67572781c.js +0 -1
  492. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-e0c1e2c67572781c.js +0 -1
  493. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-e0c1e2c67572781c.js +0 -1
  494. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-e0c1e2c67572781c.js +0 -1
  495. package/_standalone/.next/static/chunks/webpack-043f40ef7816d8c4.js +0 -1
  496. package/_standalone/.next/static/css/8b1f248d6540e52f.css +0 -1
  497. package/_standalone/lib/core/__tests__/synonym-dict.test.ts +0 -82
  498. package/app/lib/core/__tests__/synonym-dict.test.ts +0 -82
  499. package/app/lib/core/synonym-dict.ts +0 -139
  500. /package/_standalone/.next/static/{0JtsgqDZLSJ6MrIZIV6gC → ixCTELNH6V05Z00pC6ZMO}/_ssgManifest.js +0 -0
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useEffect, useLayoutEffect, useRef, useState, useCallback, useMemo } from 'react';
4
+ import { createPortal } from 'react-dom';
4
5
  import { Send, StopCircle, X, Plus, FileText, ImageIcon } from 'lucide-react';
5
6
  import { useLocale } from '@/lib/stores/locale-store';
6
7
  import type { AskMode, Message } from '@/lib/types';
@@ -15,6 +16,7 @@ import MessageList from '@/components/ask/MessageList';
15
16
  import MentionPopover from '@/components/ask/MentionPopover';
16
17
  import SlashCommandPopover from '@/components/ask/SlashCommandPopover';
17
18
  import SessionHistory from '@/components/ask/SessionHistory';
19
+ import SessionHistoryPanel from '@/components/ask/SessionHistoryPanel';
18
20
  import AskHeader from '@/components/ask/AskHeader';
19
21
  import FileChip from '@/components/ask/FileChip';
20
22
  import AgentSelectorCapsule from '@/components/ask/AgentSelectorCapsule';
@@ -97,6 +99,8 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
97
99
  const [showHistory, setShowHistory] = useState(false);
98
100
  const [isDragOver, setIsDragOver] = useState(false);
99
101
  const [showAttachMenu, setShowAttachMenu] = useState(false);
102
+ const attachButtonRef = useRef<HTMLButtonElement>(null);
103
+ const [attachMenuPos, setAttachMenuPos] = useState<{ top: number; left: number } | null>(null);
100
104
 
101
105
  const [selectedSkill, setSelectedSkill] = useState<SlashItem | null>(null);
102
106
  const selectedSkillRef = useRef(selectedSkill);
@@ -182,6 +186,31 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
182
186
  return () => window.removeEventListener('mindos:inject-ask-files', handler);
183
187
  }, []);
184
188
 
189
+ // Position the attach menu popover above the button (using Portal to avoid clipping)
190
+ useEffect(() => {
191
+ if (!showAttachMenu || !attachButtonRef.current) {
192
+ setAttachMenuPos(null);
193
+ return;
194
+ }
195
+ const rect = attachButtonRef.current.getBoundingClientRect();
196
+ setAttachMenuPos({
197
+ top: rect.top - 8, // 8px above button
198
+ left: rect.left,
199
+ });
200
+ }, [showAttachMenu]);
201
+
202
+ // Close attach menu when clicking outside
203
+ useEffect(() => {
204
+ if (!showAttachMenu) return;
205
+ const handleClickOutside = (e: MouseEvent) => {
206
+ if (attachButtonRef.current && !attachButtonRef.current.contains(e.target as Node)) {
207
+ setShowAttachMenu(false);
208
+ }
209
+ };
210
+ document.addEventListener('mousedown', handleClickOutside);
211
+ return () => document.removeEventListener('mousedown', handleClickOutside);
212
+ }, [showAttachMenu]);
213
+
185
214
  // Home suggestion chip click — inject text into input
186
215
  useEffect(() => {
187
216
  if (!isHome) return;
@@ -534,7 +563,7 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
534
563
  />
535
564
 
536
565
  {showHistory && (
537
- <SessionHistory
566
+ <SessionHistoryPanel
538
567
  sessions={session.sessions}
539
568
  activeSessionId={session.activeSessionId}
540
569
  onLoad={handleLoadSession}
@@ -542,16 +571,13 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
542
571
  onRename={session.renameSession}
543
572
  onTogglePin={session.togglePinSession}
544
573
  onClearAll={session.clearAllSessions}
545
- labels={{
546
- title: t.ask.sessionHistory ?? 'Session History',
547
- clearAll: t.ask.clearAll ?? 'Clear all',
548
- confirmClear: t.ask.confirmClear ?? 'Confirm clear?',
549
- noSessions: t.ask.noSessions ?? 'No saved sessions.',
550
- rename: t.ask.renameSession ?? 'Rename',
551
- }}
574
+ onClose={() => setShowHistory(false)}
575
+ onNewChat={handleResetSession}
552
576
  />
553
577
  )}
554
578
 
579
+ {!showHistory && (
580
+ <>
555
581
  {/* Messages — home variant hides empty state unless maximized (suggestions rendered externally in normal mode) */}
556
582
  <div className="flex-1 min-h-0 flex flex-col">
557
583
  {!isHome && (
@@ -664,6 +690,7 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
664
690
  {/* + attach button with mini menu */}
665
691
  <div className="relative shrink-0">
666
692
  <button
693
+ ref={attachButtonRef}
667
694
  type="button"
668
695
  onClick={() => setShowAttachMenu(v => !v)}
669
696
  className="p-2 rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/60 transition-colors"
@@ -671,28 +698,39 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
671
698
  >
672
699
  <Plus size={inputIconSize} />
673
700
  </button>
674
- {showAttachMenu && (
675
- <div className="absolute bottom-full left-0 mb-1.5 py-1 rounded-xl border border-border/60 bg-card shadow-lg z-50 min-w-[150px] animate-in fade-in-0 slide-in-from-bottom-2 duration-150">
676
- <button
677
- type="button"
678
- className="flex w-full items-center gap-2.5 px-3 py-2 text-xs hover:bg-muted transition-colors text-left rounded-lg"
679
- onClick={() => { setShowAttachMenu(false); upload.uploadInputRef.current?.click(); }}
680
- >
681
- <FileText size={12} className="shrink-0 text-muted-foreground" />
682
- {t.ask.attachFileLabel}
683
- </button>
684
- <button
685
- type="button"
686
- className="flex w-full items-center gap-2.5 px-3 py-2 text-xs hover:bg-muted transition-colors text-left rounded-lg"
687
- onClick={() => { setShowAttachMenu(false); imageInputRef.current?.click(); }}
688
- >
689
- <ImageIcon size={12} className="shrink-0 text-muted-foreground" />
690
- {t.ask.attachImageLabel}
691
- </button>
692
- </div>
693
- )}
694
701
  </div>
695
702
 
703
+ {/* Attach menu rendered as Portal to avoid clipping by overflow-hidden parent */}
704
+ {mounted && showAttachMenu && attachMenuPos && createPortal(
705
+ <div
706
+ className="fixed py-1 rounded-xl border border-border/60 bg-card shadow-lg z-50 min-w-[150px] animate-in fade-in-0 slide-in-from-bottom-2 duration-150"
707
+ style={{
708
+ top: `${attachMenuPos.top}px`,
709
+ left: `${attachMenuPos.left}px`,
710
+ transform: 'translateY(-100%)', // Position above the button
711
+ }}
712
+ onClick={(e) => e.stopPropagation()}
713
+ >
714
+ <button
715
+ type="button"
716
+ className="flex w-full items-center gap-2.5 px-3 py-2 text-xs hover:bg-muted transition-colors text-left rounded-lg"
717
+ onClick={() => { setShowAttachMenu(false); upload.uploadInputRef.current?.click(); }}
718
+ >
719
+ <FileText size={12} className="shrink-0 text-muted-foreground" />
720
+ {t.ask.attachFileLabel}
721
+ </button>
722
+ <button
723
+ type="button"
724
+ className="flex w-full items-center gap-2.5 px-3 py-2 text-xs hover:bg-muted transition-colors text-left rounded-lg"
725
+ onClick={() => { setShowAttachMenu(false); imageInputRef.current?.click(); }}
726
+ >
727
+ <ImageIcon size={12} className="shrink-0 text-muted-foreground" />
728
+ {t.ask.attachImageLabel}
729
+ </button>
730
+ </div>,
731
+ document.body
732
+ )}
733
+
696
734
  <input
697
735
  ref={upload.uploadInputRef}
698
736
  type="file"
@@ -773,6 +811,8 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
773
811
  </div>
774
812
  </div>
775
813
  </div>
814
+ </>
815
+ )}
776
816
  </div>
777
817
  );
778
818
  }
@@ -205,9 +205,13 @@ export default memo(function AskHeader({
205
205
  {!hideTitle && (
206
206
  <div className="flex items-center gap-2 min-w-0">
207
207
  <div className="w-6 h-6 rounded-lg bg-[var(--amber)]/10 flex items-center justify-center shrink-0">
208
- <Sparkles size={13} className="text-[var(--amber)]" />
208
+ {showHistory ? <History size={13} className="text-[var(--amber)]" /> : <Sparkles size={13} className="text-[var(--amber)]" />}
209
209
  </div>
210
- {hasMultipleSessions && activeTitle ? (
210
+ {showHistory ? (
211
+ <span className="text-sm font-medium text-[var(--amber)]">
212
+ {t.ask?.sessionHistory ?? 'Session History'}
213
+ </span>
214
+ ) : hasMultipleSessions && activeTitle ? (
211
215
  <button
212
216
  ref={switcherRef}
213
217
  type="button"
@@ -180,7 +180,7 @@ export default function ProviderModelCapsule({
180
180
  const goUp = rect.top > window.innerHeight - rect.bottom && rect.top > 280;
181
181
  setDropdownStyle({
182
182
  position: 'fixed',
183
- left: Math.min(rect.left, window.innerWidth - 230),
183
+ left: Math.min(rect.left, window.innerWidth - 270),
184
184
  ...(goUp ? { bottom: window.innerHeight - rect.top + 6 } : { top: rect.bottom + 6 }),
185
185
  zIndex: 50,
186
186
  });
@@ -487,7 +487,7 @@ export default function ProviderModelCapsule({
487
487
  ref={providerPanelRef}
488
488
  role="listbox"
489
489
  aria-label={t.ask?.providerCapsule ?? 'Provider'}
490
- className="w-[220px] rounded-lg border border-border bg-card shadow-lg py-1 animate-in fade-in-0 zoom-in-95 duration-100"
490
+ className="w-[260px] rounded-lg border border-border bg-card shadow-lg py-1 animate-in fade-in-0 zoom-in-95 duration-100"
491
491
  style={{ maxHeight: '70vh', overflowY: 'auto' }}
492
492
  >
493
493
  {providerIds.map((id) => {
@@ -512,15 +512,17 @@ export default function ProviderModelCapsule({
512
512
  <button
513
513
  type="button" role="option" aria-selected={isSelected}
514
514
  onClick={() => handleSelectProvider(id as ProviderSelection)}
515
- className="flex flex-1 items-center gap-2 px-3 py-1.5 min-w-0"
515
+ className="flex flex-1 items-center gap-2 px-3 py-1.5 min-w-0 text-left"
516
516
  >
517
- <div className="flex-1 min-w-0 truncate">
518
- <span className={`text-xs ${isSelected ? 'font-medium text-foreground' : 'text-foreground/80'}`}>
519
- {provName}
517
+ <span className={`shrink-0 text-xs ${isSelected ? 'font-medium text-foreground' : 'text-foreground/80'}`}>
518
+ {provName}
519
+ </span>
520
+ {provModel && (
521
+ <span className="min-w-0 truncate rounded bg-muted/70 px-1.5 py-px text-[10px] font-mono leading-tight text-muted-foreground">
522
+ {provModel}
520
523
  </span>
521
- <span className="text-2xs text-muted-foreground ml-1.5">{provModel}</span>
522
- </div>
523
- {isSelected && <Check size={11} className="shrink-0 text-[var(--amber)]" />}
524
+ )}
525
+ {isSelected && <Check size={11} className="shrink-0 ml-auto text-[var(--amber)]" />}
524
526
  </button>
525
527
  {canExpand && (
526
528
  <button
@@ -0,0 +1,398 @@
1
+ 'use client';
2
+
3
+ import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
4
+ import { Search, Trash2, Pencil, Pin, PinOff, FolderInput, MessageSquare, SquarePen, X } from 'lucide-react';
5
+ import type { ChatSession } from '@/lib/types';
6
+ import { sessionTitle } from '@/hooks/useAskSession';
7
+ import { useLocale } from '@/lib/stores/locale-store';
8
+
9
+ interface SessionHistoryPanelProps {
10
+ sessions: ChatSession[];
11
+ activeSessionId: string | null;
12
+ onLoad: (id: string) => void;
13
+ onDelete: (id: string) => void;
14
+ onRename: (id: string, title: string) => void;
15
+ onTogglePin: (id: string) => void;
16
+ onClearAll: () => void;
17
+ onClose: () => void;
18
+ onNewChat: () => void;
19
+ }
20
+
21
+ // ── Helpers ──
22
+
23
+ function formatRelativeTime(date: Date): string {
24
+ const now = Date.now();
25
+ const diff = now - date.getTime();
26
+ const mins = Math.floor(diff / 60000);
27
+ if (mins < 1) return 'just now';
28
+ if (mins < 60) return `${mins}m ago`;
29
+ const hours = Math.floor(mins / 60);
30
+ if (hours < 24) return `${hours}h ago`;
31
+ const days = Math.floor(hours / 24);
32
+ if (days < 7) return `${days}d ago`;
33
+ return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
34
+ }
35
+
36
+ function getTimeGroup(ts: number): 'pinned' | 'today' | 'yesterday' | 'week' | 'older' {
37
+ const now = new Date();
38
+ const date = new Date(ts);
39
+ const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
40
+ const startOfYesterday = startOfToday - 86400000;
41
+ const startOfWeek = startOfToday - now.getDay() * 86400000;
42
+ if (ts >= startOfToday) return 'today';
43
+ if (ts >= startOfYesterday) return 'yesterday';
44
+ if (ts >= startOfWeek) return 'week';
45
+ return 'older';
46
+ }
47
+
48
+ function sessionPreview(s: ChatSession): string {
49
+ const firstUser = s.messages.find(m => m.role === 'user');
50
+ if (!firstUser) return '';
51
+ const text = firstUser.content.replace(/\s+/g, ' ').trim();
52
+ return text.length > 60 ? `${text.slice(0, 60)}...` : text;
53
+ }
54
+
55
+ // ── Main Component ──
56
+
57
+ export default function SessionHistoryPanel({
58
+ sessions, activeSessionId,
59
+ onLoad, onDelete, onRename, onTogglePin, onClearAll,
60
+ onClose, onNewChat,
61
+ }: SessionHistoryPanelProps) {
62
+ const { t } = useLocale();
63
+ const ask = t.ask;
64
+ const [query, setQuery] = useState('');
65
+ const [editingId, setEditingId] = useState<string | null>(null);
66
+ const [editValue, setEditValue] = useState('');
67
+ const [confirmClearAll, setConfirmClearAll] = useState(false);
68
+ const clearTimer = useRef<ReturnType<typeof setTimeout>>(undefined);
69
+ const searchRef = useRef<HTMLInputElement>(null);
70
+ const inputRef = useRef<HTMLInputElement>(null);
71
+
72
+ // Focus search on mount
73
+ useEffect(() => { searchRef.current?.focus(); }, []);
74
+
75
+ // Focus rename input
76
+ useEffect(() => { if (editingId) setTimeout(() => inputRef.current?.focus(), 0); }, [editingId]);
77
+
78
+ // Clear timer cleanup
79
+ useEffect(() => () => { if (clearTimer.current) clearTimeout(clearTimer.current); }, []);
80
+
81
+ // Filter sessions by search query
82
+ const filtered = useMemo(() => {
83
+ if (!query.trim()) return sessions;
84
+ const q = query.toLowerCase();
85
+ return sessions.filter(s => {
86
+ const title = sessionTitle(s).toLowerCase();
87
+ if (title.includes(q)) return true;
88
+ return s.messages.some(m => m.content.toLowerCase().includes(q));
89
+ });
90
+ }, [sessions, query]);
91
+
92
+ // Group sessions by time
93
+ const groups = useMemo(() => {
94
+ const pinned: ChatSession[] = [];
95
+ const today: ChatSession[] = [];
96
+ const yesterday: ChatSession[] = [];
97
+ const week: ChatSession[] = [];
98
+ const older: ChatSession[] = [];
99
+
100
+ for (const s of filtered) {
101
+ if (s.pinned) { pinned.push(s); continue; }
102
+ const group = getTimeGroup(s.updatedAt);
103
+ if (group === 'today') today.push(s);
104
+ else if (group === 'yesterday') yesterday.push(s);
105
+ else if (group === 'week') week.push(s);
106
+ else older.push(s);
107
+ }
108
+ return { pinned, today, yesterday, week, older };
109
+ }, [filtered]);
110
+
111
+ const pinnedCount = sessions.filter(s => s.pinned).length;
112
+ // Only count sessions with messages (non-empty)
113
+ const totalCount = sessions.filter(s => s.messages.length > 0).length;
114
+
115
+ const handleLoad = useCallback((id: string) => {
116
+ onLoad(id);
117
+ onClose();
118
+ }, [onLoad, onClose]);
119
+
120
+ const handleNewChat = useCallback(() => {
121
+ onNewChat();
122
+ onClose();
123
+ }, [onNewChat, onClose]);
124
+
125
+ const startRename = useCallback((s: ChatSession) => {
126
+ setEditingId(s.id);
127
+ setEditValue(sessionTitle(s));
128
+ }, []);
129
+
130
+ const commitRename = useCallback(() => {
131
+ if (editingId && editValue.trim()) {
132
+ onRename(editingId, editValue.trim());
133
+ }
134
+ setEditingId(null);
135
+ }, [editingId, editValue, onRename]);
136
+
137
+ const handleClearAll = useCallback(() => {
138
+ if (!confirmClearAll) {
139
+ setConfirmClearAll(true);
140
+ if (clearTimer.current) clearTimeout(clearTimer.current);
141
+ clearTimer.current = setTimeout(() => setConfirmClearAll(false), 3000);
142
+ return;
143
+ }
144
+ if (clearTimer.current) clearTimeout(clearTimer.current);
145
+ onClearAll();
146
+ setConfirmClearAll(false);
147
+ }, [confirmClearAll, onClearAll]);
148
+
149
+ // Keyboard: Esc to close
150
+ useEffect(() => {
151
+ const handler = (e: KeyboardEvent) => {
152
+ if (e.key === 'Escape' && !editingId) onClose();
153
+ };
154
+ document.addEventListener('keydown', handler);
155
+ return () => document.removeEventListener('keydown', handler);
156
+ }, [onClose, editingId]);
157
+
158
+ const renderGroup = (label: string, items: ChatSession[]) => {
159
+ if (items.length === 0) return null;
160
+ return (
161
+ <div key={label}>
162
+ <div className="text-2xs font-medium text-muted-foreground/50 uppercase tracking-wider px-1 py-2">
163
+ {label}
164
+ </div>
165
+ <div className="flex flex-col gap-1">
166
+ {items.map(s => (
167
+ <SessionCard
168
+ key={s.id}
169
+ session={s}
170
+ isActive={s.id === activeSessionId}
171
+ editing={editingId === s.id}
172
+ editValue={editValue}
173
+ onEditValueChange={setEditValue}
174
+ inputRef={inputRef}
175
+ onLoad={() => handleLoad(s.id)}
176
+ onStartRename={() => startRename(s)}
177
+ onCommitRename={commitRename}
178
+ onCancelRename={() => setEditingId(null)}
179
+ onDelete={() => onDelete(s.id)}
180
+ onTogglePin={() => onTogglePin(s.id)}
181
+ ask={ask}
182
+ />
183
+ ))}
184
+ </div>
185
+ </div>
186
+ );
187
+ };
188
+
189
+ const hasResults = filtered.length > 0;
190
+
191
+ return (
192
+ <div className="flex flex-col flex-1 min-h-0 animate-in fade-in-0 duration-150">
193
+ {/* Search bar */}
194
+ <div className="px-4 pt-3 pb-2 shrink-0">
195
+ <div className="relative">
196
+ <Search size={13} className="absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground/50" />
197
+ <input
198
+ ref={searchRef}
199
+ type="text"
200
+ value={query}
201
+ onChange={e => setQuery(e.target.value)}
202
+ placeholder={ask?.historySearch ?? 'Search conversations...'}
203
+ className="w-full pl-8 pr-8 py-2 text-xs rounded-lg border border-border bg-background text-foreground placeholder:text-muted-foreground/40 outline-none focus-visible:border-[var(--amber)]/40 transition-colors"
204
+ />
205
+ {query && (
206
+ <button
207
+ type="button"
208
+ onClick={() => setQuery('')}
209
+ className="absolute right-2 top-1/2 -translate-y-1/2 p-0.5 rounded text-muted-foreground/40 hover:text-foreground"
210
+ >
211
+ <X size={12} />
212
+ </button>
213
+ )}
214
+ </div>
215
+ </div>
216
+
217
+ {/* Stats bar */}
218
+ <div className="flex items-center justify-between px-4 pb-2 shrink-0">
219
+ <span className="text-2xs text-muted-foreground/60">
220
+ {ask?.historyStats?.(totalCount) ?? `${totalCount} conversations`}
221
+ {pinnedCount > 0 && <> &middot; {pinnedCount} {ask?.historyPinned ?? 'pinned'}</>}
222
+ </span>
223
+ <button
224
+ type="button"
225
+ onClick={handleNewChat}
226
+ className="flex items-center gap-1 text-2xs text-[var(--amber)] hover:text-[var(--amber)]/80 transition-colors"
227
+ >
228
+ <SquarePen size={11} />
229
+ <span>{t.hints?.newChat ?? 'New chat'}</span>
230
+ </button>
231
+ </div>
232
+
233
+ {/* Scrollable list */}
234
+ <div className="flex-1 overflow-y-auto min-h-0 px-3 pb-3">
235
+ {hasResults ? (
236
+ <div className="flex flex-col gap-1">
237
+ {renderGroup(ask?.historyPinned ?? 'Pinned', groups.pinned)}
238
+ {renderGroup(ask?.historyToday ?? 'Today', groups.today)}
239
+ {renderGroup(ask?.historyYesterday ?? 'Yesterday', groups.yesterday)}
240
+ {renderGroup(ask?.historyThisWeek ?? 'This week', groups.week)}
241
+ {renderGroup(ask?.historyOlder ?? 'Older', groups.older)}
242
+ </div>
243
+ ) : (
244
+ <div className="flex flex-col items-center justify-center py-12 text-center">
245
+ <MessageSquare size={32} className="text-muted-foreground/20 mb-3" />
246
+ <p className="text-sm text-muted-foreground/60">
247
+ {query ? 'No matching conversations' : (ask?.historyEmpty ?? 'No conversations yet')}
248
+ </p>
249
+ {!query && (
250
+ <p className="text-2xs text-muted-foreground/40 mt-1">
251
+ {ask?.historyEmptyHint ?? 'Start a new chat to begin'}
252
+ </p>
253
+ )}
254
+ </div>
255
+ )}
256
+ </div>
257
+
258
+ {/* Footer */}
259
+ {totalCount > 0 && (
260
+ <div className="flex items-center justify-between px-4 py-2.5 border-t border-border/40 shrink-0">
261
+ <button
262
+ type="button"
263
+ onClick={handleClearAll}
264
+ className={`text-2xs px-2 py-0.5 rounded-md transition-colors ${
265
+ confirmClearAll
266
+ ? 'bg-error/10 text-error font-medium'
267
+ : 'text-muted-foreground/50 hover:text-error hover:bg-muted'
268
+ }`}
269
+ >
270
+ <span className="flex items-center gap-1">
271
+ <Trash2 size={10} />
272
+ {confirmClearAll ? (ask?.confirmClear ?? 'Confirm clear?') : (ask?.clearAll ?? 'Clear all')}
273
+ </span>
274
+ </button>
275
+ <span className="text-2xs text-muted-foreground/40 tabular-nums">
276
+ {ask?.historyCapacity?.(totalCount) ?? `${totalCount} of 30`}
277
+ </span>
278
+ </div>
279
+ )}
280
+ </div>
281
+ );
282
+ }
283
+
284
+ // ── Session Card ──
285
+
286
+ function SessionCard({
287
+ session: s, isActive, editing, editValue, onEditValueChange, inputRef,
288
+ onLoad, onStartRename, onCommitRename, onCancelRename, onDelete, onTogglePin,
289
+ ask,
290
+ }: {
291
+ session: ChatSession;
292
+ isActive: boolean;
293
+ editing: boolean;
294
+ editValue: string;
295
+ onEditValueChange: (v: string) => void;
296
+ inputRef: React.RefObject<HTMLInputElement | null>;
297
+ onLoad: () => void;
298
+ onStartRename: () => void;
299
+ onCommitRename: () => void;
300
+ onCancelRename: () => void;
301
+ onDelete: () => void;
302
+ onTogglePin: () => void;
303
+ ask: Record<string, any>;
304
+ }) {
305
+ const title = sessionTitle(s);
306
+ const preview = sessionPreview(s);
307
+ const msgCount = s.messages.length;
308
+
309
+ return (
310
+ <div
311
+ className={`group relative rounded-lg transition-colors cursor-pointer ${
312
+ isActive
313
+ ? 'bg-[var(--amber)]/8 border border-[var(--amber)]/15'
314
+ : 'hover:bg-muted/60 border border-transparent'
315
+ }`}
316
+ onClick={onLoad}
317
+ >
318
+ {/* Active indicator */}
319
+ {isActive && (
320
+ <span className="absolute left-0 top-3 bottom-3 w-[2px] rounded-r-full bg-[var(--amber)]" />
321
+ )}
322
+
323
+ <div className="px-3 py-2.5">
324
+ {/* Title row */}
325
+ <div className="flex items-center gap-1.5 mb-0.5">
326
+ {s.pinned && <Pin size={10} className="shrink-0 text-[var(--amber)]/60 -rotate-45" />}
327
+ {editing ? (
328
+ <input
329
+ ref={inputRef}
330
+ type="text"
331
+ value={editValue}
332
+ onChange={e => onEditValueChange(e.target.value)}
333
+ onBlur={onCommitRename}
334
+ onKeyDown={e => {
335
+ if (e.key === 'Enter') { e.preventDefault(); onCommitRename(); }
336
+ if (e.key === 'Escape') { e.preventDefault(); onCancelRename(); }
337
+ }}
338
+ onClick={e => e.stopPropagation()}
339
+ className="flex-1 min-w-0 bg-transparent border-b border-[var(--amber)] outline-none text-xs font-medium text-foreground"
340
+ />
341
+ ) : (
342
+ <span className="flex-1 min-w-0 text-xs font-medium text-foreground truncate">
343
+ {title}
344
+ </span>
345
+ )}
346
+ <span className="text-2xs text-muted-foreground/40 shrink-0 tabular-nums">
347
+ {formatRelativeTime(new Date(s.updatedAt))}
348
+ </span>
349
+ </div>
350
+
351
+ {/* Preview */}
352
+ {!editing && preview && (
353
+ <p className="text-2xs text-muted-foreground/50 truncate mt-0.5 pl-0.5">
354
+ {preview}
355
+ </p>
356
+ )}
357
+
358
+ {/* Meta row */}
359
+ {!editing && (
360
+ <div className="flex items-center justify-between mt-1.5">
361
+ <span className="text-2xs text-muted-foreground/40 flex items-center gap-1">
362
+ <MessageSquare size={9} />
363
+ {ask?.historyMsgs?.(msgCount) ?? `${msgCount} msgs`}
364
+ </span>
365
+
366
+ {/* Action buttons — visible on hover */}
367
+ <div className="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity" onClick={e => e.stopPropagation()}>
368
+ <button
369
+ type="button"
370
+ onClick={onTogglePin}
371
+ className={`p-1 rounded-md transition-colors ${s.pinned ? 'text-[var(--amber)] hover:text-muted-foreground' : 'text-muted-foreground/40 hover:text-[var(--amber)]'}`}
372
+ title={s.pinned ? 'Unpin' : 'Pin'}
373
+ >
374
+ {s.pinned ? <PinOff size={11} /> : <Pin size={11} />}
375
+ </button>
376
+ <button
377
+ type="button"
378
+ onClick={onStartRename}
379
+ className="p-1 rounded-md text-muted-foreground/40 hover:text-foreground hover:bg-muted/60 transition-colors"
380
+ title={ask?.renameSession ?? 'Rename'}
381
+ >
382
+ <Pencil size={11} />
383
+ </button>
384
+ <button
385
+ type="button"
386
+ onClick={onDelete}
387
+ className="p-1 rounded-md text-muted-foreground/40 hover:text-error hover:bg-error/5 transition-colors"
388
+ title="Delete"
389
+ >
390
+ <Trash2 size={11} />
391
+ </button>
392
+ </div>
393
+ </div>
394
+ )}
395
+ </div>
396
+ </div>
397
+ );
398
+ }
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useState } from 'react';
4
- import { usePathname, useSearchParams } from 'next/navigation';
4
+ import { useRouter, usePathname, useSearchParams } from 'next/navigation';
5
5
  import { Globe, Loader2, RefreshCw, Settings } from 'lucide-react';
6
6
  import { useMcpData } from '@/lib/stores/mcp-store';
7
7
  import { useA2aRegistry } from '@/hooks/useA2aRegistry';
@@ -27,6 +27,7 @@ export default function AgentsPanel({
27
27
  }: AgentsPanelProps) {
28
28
  const { t } = useLocale();
29
29
  const p = t.panels.agents;
30
+ const router = useRouter();
30
31
  const mcp = useMcpData();
31
32
  const pathname = usePathname();
32
33
  const searchParams = useSearchParams();
@@ -42,6 +43,10 @@ export default function AgentsPanel({
42
43
  setRefreshing(false);
43
44
  };
44
45
 
46
+ const handleChannelsClick = () => {
47
+ router.push('/agents?tab=channels');
48
+ };
49
+
45
50
  const openAdvancedConfig = () => {
46
51
  window.dispatchEvent(new CustomEvent('mindos:open-settings', { detail: { tab: 'mcp' } }));
47
52
  };
@@ -84,6 +89,8 @@ export default function AgentsPanel({
84
89
  copy={hubCopy}
85
90
  connectedCount={connected.length}
86
91
  mcpEnabled={mcp.status?.connectionMode?.mcp ?? false}
92
+ channelsActive={isChannelsTab}
93
+ onChannelsClick={handleChannelsClick}
87
94
  />
88
95
  );
89
96
 
@@ -12,6 +12,7 @@ import { type Provider, generateProviderId } from '@/lib/custom-endpoints';
12
12
  import { useCustomProviderForm, type TestResult } from './useCustomProviderForm';
13
13
  import CustomProviderFields from './CustomProviderFields';
14
14
  import { TestButton } from './TestButton';
15
+ import WebPortSection from './WebPortSection';
15
16
 
16
17
  export function AiTab({ data, updateAi, updateAgent, t }: AiTabProps) {
17
18
  const { locale } = useLocale();
@@ -367,7 +368,10 @@ export function AiTab({ data, updateAi, updateAgent, t }: AiTabProps) {
367
368
  )}
368
369
  </SettingCard>
369
370
 
370
- {/* ── Card 3: Display Mode ── */}
371
+ {/* ── Card 3: Web Server Port ── */}
372
+ <WebPortSection m={t.settings?.mcp ?? {}} />
373
+
374
+ {/* ── Card 4: Display Mode ── */}
371
375
  <AskDisplayMode />
372
376
  </div>
373
377
  );