@geminilight/mindos 0.6.53 → 0.6.55

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 (512) hide show
  1. package/README.md +27 -5
  2. package/README_zh.md +27 -5
  3. package/_standalone/.mindos-build-version +1 -1
  4. package/_standalone/.next/BUILD_ID +1 -1
  5. package/_standalone/.next/app-path-routes-manifest.json +28 -25
  6. package/_standalone/.next/build-manifest.json +3 -3
  7. package/_standalone/.next/cache/.previewinfo +1 -1
  8. package/_standalone/.next/cache/.rscinfo +1 -1
  9. package/_standalone/.next/cache/config.json +3 -3
  10. package/_standalone/.next/prerender-manifest.json +3 -3
  11. package/_standalone/.next/react-loadable-manifest.json +18 -2
  12. package/_standalone/.next/routes-manifest.json +18 -0
  13. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  14. package/_standalone/.next/server/app/_global-error/page.js +1 -1
  15. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  16. package/_standalone/.next/server/app/_global-error.html +2 -2
  17. package/_standalone/.next/server/app/_global-error.rsc +2 -2
  18. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  19. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  21. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  22. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  23. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  24. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  25. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  26. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  27. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  28. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  29. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/agents/page.js +3 -3
  31. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  32. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  35. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  41. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  42. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  43. package/_standalone/.next/server/app/api/ask/route.js +5 -5
  44. package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
  45. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  46. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  47. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  48. package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
  49. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  50. package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
  51. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
  53. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  54. package/_standalone/.next/server/app/api/export/route.js +2 -2
  55. package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
  56. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  58. package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
  59. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  60. package/_standalone/.next/server/app/api/file/raw/route.js +1 -0
  61. package/_standalone/.next/server/app/api/file/raw/route.js.nft.json +1 -0
  62. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -0
  63. package/_standalone/.next/server/app/api/file/route.js +1 -1
  64. package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
  65. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  66. package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  67. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  68. package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  69. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  70. package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
  71. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  72. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  73. package/_standalone/.next/server/app/api/inbox/route.js +1 -1
  74. package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
  75. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  76. package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
  77. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  78. package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
  79. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  80. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  81. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  82. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  83. package/_standalone/.next/server/app/api/mcp/status/route.js +1 -1
  84. package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
  85. package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
  86. package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
  87. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  88. package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
  89. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  91. package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  92. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  93. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  94. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/api/settings/route.js +1 -1
  96. package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  97. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  98. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  99. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  100. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  102. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  103. package/_standalone/.next/server/app/api/setup/route.js +1 -1
  104. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  105. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  106. package/_standalone/.next/server/app/api/sync/route.js +1 -1
  107. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  108. package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
  109. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  110. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  111. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  112. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  113. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  114. package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
  115. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  116. package/_standalone/.next/server/app/changes/page.js +2 -2
  117. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  118. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  119. package/_standalone/.next/server/app/echo/[segment]/page.js +3 -3
  120. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  121. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  122. package/_standalone/.next/server/app/echo/page.js +1 -1
  123. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  124. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  125. package/_standalone/.next/server/app/explore/page.js +2 -2
  126. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  127. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  128. package/_standalone/.next/server/app/help/page.js +2 -2
  129. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  130. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  131. package/_standalone/.next/server/app/inbox/history/page.js +2 -0
  132. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -0
  133. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -0
  134. package/_standalone/.next/server/app/login/page.js +2 -2
  135. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  136. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  137. package/_standalone/.next/server/app/page.js +3 -3
  138. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  139. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  140. package/_standalone/.next/server/app/setup/page.js +2 -2
  141. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  142. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  143. package/_standalone/.next/server/app/trash/page.js +3 -3
  144. package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
  145. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  146. package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
  147. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  148. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  149. package/_standalone/.next/server/app/wiki/page.js +2 -0
  150. package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -0
  151. package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -0
  152. package/_standalone/.next/server/app-paths-manifest.json +28 -25
  153. package/_standalone/.next/server/chunks/1981.js +52 -0
  154. package/_standalone/.next/server/chunks/2190.js +2 -2
  155. package/_standalone/.next/server/chunks/2364.js +2 -0
  156. package/_standalone/.next/server/chunks/357.js +1 -0
  157. package/_standalone/.next/server/chunks/530.js +219 -0
  158. package/_standalone/.next/server/chunks/6539.js +1 -1
  159. package/_standalone/.next/server/chunks/8388.js +2 -2
  160. package/_standalone/.next/server/chunks/953.js +4 -4
  161. package/_standalone/.next/server/middleware-build-manifest.js +1 -1
  162. package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  163. package/_standalone/.next/server/next-font-manifest.js +1 -1
  164. package/_standalone/.next/server/next-font-manifest.json +1 -1
  165. package/_standalone/.next/server/pages/500.html +2 -2
  166. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  167. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  168. package/_standalone/.next/static/QXZErVsiRQxfqUnWMUsH6/_buildManifest.js +1 -0
  169. package/_standalone/.next/static/chunks/1053-2874859f7caefa0f.js +29 -0
  170. package/_standalone/.next/static/chunks/178-105779afb62d36d9.js +1 -0
  171. package/_standalone/.next/static/chunks/1814.b08e9fb85dd3b13c.js +1 -0
  172. package/_standalone/.next/static/chunks/{1880-3ec02adc80531825.js → 1880-7abf971bcfd2389b.js} +2 -2
  173. package/_standalone/.next/static/chunks/{3160-83a7e0b94414b3ac.js → 2218-d54538000574ffef.js} +1 -1
  174. package/_standalone/.next/static/chunks/254-32719a9bea2e74f0.js +1 -0
  175. package/_standalone/.next/static/chunks/362.a77be2f206db7b19.js +1 -0
  176. package/_standalone/.next/static/chunks/4237-ffc6e7c15d4007b6.js +1 -0
  177. package/_standalone/.next/static/chunks/7035-2af69391c7b1ad95.js +1 -0
  178. package/_standalone/.next/static/chunks/7322-d67d05067544864c.js +1 -0
  179. package/_standalone/.next/static/chunks/{6926-4af497b83952fa87.js → 8409-de5726a4a278d28f.js} +1 -1
  180. package/_standalone/.next/static/chunks/8753-ea9db680b0f70f25.js +1 -0
  181. package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/{route-b07a5983e85bc5e3.js → route-e240db6d5049d336.js} +1 -1
  182. package/_standalone/.next/static/chunks/app/_global-error/{page-b07a5983e85bc5e3.js → page-e240db6d5049d336.js} +1 -1
  183. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-f006a70f6889eb56.js +1 -0
  184. package/_standalone/.next/static/chunks/app/agents/page-bd522e428e3acb78.js +5 -0
  185. package/_standalone/.next/static/chunks/app/api/a2a/agents/{route-b07a5983e85bc5e3.js → route-e240db6d5049d336.js} +1 -1
  186. package/_standalone/.next/static/chunks/app/api/a2a/delegations/{route-b07a5983e85bc5e3.js → route-e240db6d5049d336.js} +1 -1
  187. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-e240db6d5049d336.js +1 -0
  188. package/_standalone/.next/static/chunks/app/api/a2a/route-e240db6d5049d336.js +1 -0
  189. package/_standalone/.next/static/chunks/app/api/acp/config/route-e240db6d5049d336.js +1 -0
  190. package/_standalone/.next/static/chunks/app/api/acp/detect/route-e240db6d5049d336.js +1 -0
  191. package/_standalone/.next/static/chunks/app/api/acp/install/route-e240db6d5049d336.js +1 -0
  192. package/_standalone/.next/static/chunks/app/api/acp/registry/route-e240db6d5049d336.js +1 -0
  193. package/_standalone/.next/static/chunks/app/api/acp/session/route-e240db6d5049d336.js +1 -0
  194. package/_standalone/.next/static/chunks/app/api/agent-activity/route-e240db6d5049d336.js +1 -0
  195. package/_standalone/.next/static/chunks/app/api/ask/route-e240db6d5049d336.js +1 -0
  196. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-e240db6d5049d336.js +1 -0
  197. package/_standalone/.next/static/chunks/app/api/auth/route-e240db6d5049d336.js +1 -0
  198. package/_standalone/.next/static/chunks/app/api/backlinks/route-e240db6d5049d336.js +1 -0
  199. package/_standalone/.next/static/chunks/app/api/bootstrap/route-e240db6d5049d336.js +1 -0
  200. package/_standalone/.next/static/chunks/app/api/changes/route-e240db6d5049d336.js +1 -0
  201. package/_standalone/.next/static/chunks/app/api/export/route-e240db6d5049d336.js +1 -0
  202. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-e240db6d5049d336.js +1 -0
  203. package/_standalone/.next/static/chunks/app/api/file/import/route-e240db6d5049d336.js +1 -0
  204. package/_standalone/.next/static/chunks/app/api/file/raw/route-e240db6d5049d336.js +1 -0
  205. package/_standalone/.next/static/chunks/app/api/file/route-e240db6d5049d336.js +1 -0
  206. package/_standalone/.next/static/chunks/app/api/files/route-e240db6d5049d336.js +1 -0
  207. package/_standalone/.next/static/chunks/app/api/git/route-e240db6d5049d336.js +1 -0
  208. package/_standalone/.next/static/chunks/app/api/graph/route-e240db6d5049d336.js +1 -0
  209. package/_standalone/.next/static/chunks/app/api/health/route-e240db6d5049d336.js +1 -0
  210. package/_standalone/.next/static/chunks/app/api/inbox/route-e240db6d5049d336.js +1 -0
  211. package/_standalone/.next/static/chunks/app/api/init/route-e240db6d5049d336.js +1 -0
  212. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-e240db6d5049d336.js +1 -0
  213. package/_standalone/.next/static/chunks/app/api/mcp/install/route-e240db6d5049d336.js +1 -0
  214. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-e240db6d5049d336.js +1 -0
  215. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-e240db6d5049d336.js +1 -0
  216. package/_standalone/.next/static/chunks/app/api/mcp/status/route-e240db6d5049d336.js +1 -0
  217. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-e240db6d5049d336.js +1 -0
  218. package/_standalone/.next/static/chunks/app/api/monitoring/route-e240db6d5049d336.js +1 -0
  219. package/_standalone/.next/static/chunks/app/api/recent-files/route-e240db6d5049d336.js +1 -0
  220. package/_standalone/.next/static/chunks/app/api/restart/route-e240db6d5049d336.js +1 -0
  221. package/_standalone/.next/static/chunks/app/api/search/route-e240db6d5049d336.js +1 -0
  222. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-e240db6d5049d336.js +1 -0
  223. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-e240db6d5049d336.js +1 -0
  224. package/_standalone/.next/static/chunks/app/api/settings/route-e240db6d5049d336.js +1 -0
  225. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-e240db6d5049d336.js +1 -0
  226. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-e240db6d5049d336.js +1 -0
  227. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-e240db6d5049d336.js +1 -0
  228. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-e240db6d5049d336.js +1 -0
  229. package/_standalone/.next/static/chunks/app/api/setup/ls/route-e240db6d5049d336.js +1 -0
  230. package/_standalone/.next/static/chunks/app/api/setup/route-e240db6d5049d336.js +1 -0
  231. package/_standalone/.next/static/chunks/app/api/skills/route-e240db6d5049d336.js +1 -0
  232. package/_standalone/.next/static/chunks/app/api/sync/route-e240db6d5049d336.js +1 -0
  233. package/_standalone/.next/static/chunks/app/api/tree-version/route-e240db6d5049d336.js +1 -0
  234. package/_standalone/.next/static/chunks/app/api/uninstall/route-e240db6d5049d336.js +1 -0
  235. package/_standalone/.next/static/chunks/app/api/update/route-e240db6d5049d336.js +1 -0
  236. package/_standalone/.next/static/chunks/app/api/update-check/route-e240db6d5049d336.js +1 -0
  237. package/_standalone/.next/static/chunks/app/api/update-status/route-e240db6d5049d336.js +1 -0
  238. package/_standalone/.next/static/chunks/app/api/workflows/route-e240db6d5049d336.js +1 -0
  239. package/_standalone/.next/static/chunks/app/changes/page-5a72144d1080a699.js +1 -0
  240. package/_standalone/.next/static/chunks/app/echo/[segment]/{page-88df174dd64b2c76.js → page-6710da1f581b2854.js} +2 -2
  241. package/_standalone/.next/static/chunks/app/echo/page-e240db6d5049d336.js +1 -0
  242. package/_standalone/.next/static/chunks/app/explore/{page-5eb2835e9e3ab4bb.js → page-d3d99308146c2240.js} +1 -1
  243. package/_standalone/.next/static/chunks/app/global-error-c37d50db6128ec01.js +1 -0
  244. package/_standalone/.next/static/chunks/app/help/page-222df603080b5fab.js +1 -0
  245. package/_standalone/.next/static/chunks/app/inbox/history/page-07819cf95cb0805f.js +1 -0
  246. package/_standalone/.next/static/chunks/app/layout-45e66033ba1bdb05.js +186 -0
  247. package/_standalone/.next/static/chunks/app/loading-e240db6d5049d336.js +1 -0
  248. package/_standalone/.next/static/chunks/app/login/{page-24236460fa7c11d0.js → page-0eeef685052869a6.js} +1 -1
  249. package/_standalone/.next/static/chunks/app/page-71bd113f66bd7617.js +7 -0
  250. package/_standalone/.next/static/chunks/app/setup/{page-99f40e9337388cda.js → page-9a81fa4d82c6351b.js} +1 -1
  251. package/_standalone/.next/static/chunks/app/trash/page-ba3802cf675d029a.js +1 -0
  252. package/_standalone/.next/static/chunks/app/view/[...path]/loading-e240db6d5049d336.js +1 -0
  253. package/_standalone/.next/static/chunks/app/view/[...path]/not-found-fc04c2bd4f35bc6f.js +1 -0
  254. package/_standalone/.next/static/chunks/app/view/[...path]/page-35da7f9f5a009292.js +12 -0
  255. package/_standalone/.next/static/chunks/app/wiki/page-d492256a93f0b8bc.js +1 -0
  256. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-e240db6d5049d336.js +1 -0
  257. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-e240db6d5049d336.js +1 -0
  258. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-e240db6d5049d336.js +1 -0
  259. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-e240db6d5049d336.js +1 -0
  260. package/_standalone/.next/static/chunks/{webpack-bbd44cbc83dc0aa4.js → webpack-73c9da80c6c1ebfe.js} +1 -1
  261. package/_standalone/.next/static/css/66f8a81e4eda06d4.css +1 -0
  262. package/_standalone/.next/static/css/a4a2b71142b311af.css +31 -0
  263. package/_standalone/.next/trace +64 -64
  264. package/_standalone/.next/types/routes.d.ts +5 -2
  265. package/_standalone/.next/types/validator.ts +27 -0
  266. package/_standalone/__tests__/agents/agents-content-dashboard.test.tsx +1 -0
  267. package/_standalone/__tests__/agents/agents-content-model.test.ts +13 -0
  268. package/_standalone/__tests__/core/inbox.test.ts +168 -0
  269. package/_standalone/__tests__/core/sync.test.ts +37 -0
  270. package/_standalone/__tests__/panels/agents-panel-hub.test.tsx +1 -0
  271. package/_standalone/__tests__/settings/update-tab-desktop.test.tsx +40 -0
  272. package/_standalone/app/globals.css +29 -3
  273. package/_standalone/components/ActivityBar.tsx +9 -9
  274. package/_standalone/components/AskFab.tsx +1 -1
  275. package/_standalone/components/Backlinks.tsx +1 -1
  276. package/_standalone/components/Breadcrumb.tsx +1 -1
  277. package/_standalone/components/CreateSpaceModal.tsx +1 -1
  278. package/_standalone/components/EchoSpotlight.tsx +14 -10
  279. package/_standalone/components/Editor.tsx +1 -1
  280. package/_standalone/components/ExportModal.tsx +3 -3
  281. package/_standalone/components/FileTree.tsx +6 -11
  282. package/_standalone/components/GuideCard.tsx +1 -1
  283. package/_standalone/components/ImportModal.tsx +1 -2
  284. package/_standalone/components/KeyboardShortcuts.tsx +1 -1
  285. package/_standalone/components/MarkdownEditor.tsx +1 -1
  286. package/_standalone/components/OnboardingView.tsx +2 -2
  287. package/_standalone/components/OrganizeToast.tsx +3 -1
  288. package/_standalone/components/Panel.tsx +27 -6
  289. package/_standalone/components/Sidebar.tsx +1 -1
  290. package/_standalone/components/SidebarLayout.tsx +30 -7
  291. package/_standalone/components/SystemPulse.tsx +16 -16
  292. package/_standalone/components/agents/AgentsOverviewSection.tsx +18 -92
  293. package/_standalone/components/agents/AgentsPanelA2aTab.tsx +67 -66
  294. package/_standalone/components/agents/AgentsPrimitives.tsx +1 -1
  295. package/_standalone/components/agents/RecentActivityFeed.tsx +6 -6
  296. package/_standalone/components/agents/SkillDetailPopover.tsx +1 -1
  297. package/_standalone/components/ask/AskHeader.tsx +1 -1
  298. package/_standalone/components/echo/EchoHero.tsx +1 -1
  299. package/_standalone/components/echo/EchoPageSections.tsx +1 -1
  300. package/_standalone/components/explore/UseCaseCard.tsx +1 -1
  301. package/_standalone/components/home/InboxSection.tsx +262 -54
  302. package/_standalone/components/panels/AgentsPanel.tsx +4 -3
  303. package/_standalone/components/panels/AgentsPanelAgentDetail.tsx +1 -1
  304. package/_standalone/components/panels/AgentsPanelHubNav.tsx +10 -6
  305. package/_standalone/components/panels/PanelHeader.tsx +1 -1
  306. package/_standalone/components/renderers/audio/AudioRenderer.tsx +79 -0
  307. package/_standalone/components/renderers/image/ImageRenderer.tsx +203 -0
  308. package/_standalone/components/renderers/pdf/PdfRenderer.tsx +57 -0
  309. package/_standalone/components/renderers/video/VideoRenderer.tsx +91 -0
  310. package/_standalone/components/settings/McpTab.tsx +154 -28
  311. package/_standalone/components/settings/PluginsTab.tsx +1 -1
  312. package/_standalone/components/settings/SettingsContent.tsx +41 -7
  313. package/_standalone/components/settings/UpdateTab.tsx +18 -2
  314. package/_standalone/components/settings/types.ts +7 -1
  315. package/_standalone/components/walkthrough/WalkthroughOverlay.tsx +1 -1
  316. package/_standalone/components/walkthrough/WalkthroughTooltip.tsx +1 -1
  317. package/_standalone/hooks/useAiOrganize.ts +14 -1
  318. package/_standalone/lib/organize-history.ts +6 -0
  319. package/_standalone/tsconfig.tsbuildinfo +1 -1
  320. package/app/app/api/file/raw/route.ts +121 -0
  321. package/app/app/api/file/route.ts +21 -0
  322. package/app/app/api/inbox/route.ts +38 -2
  323. package/app/app/api/mcp/status/route.ts +1 -0
  324. package/app/app/api/settings/route.ts +13 -0
  325. package/app/app/api/setup/route.ts +11 -1
  326. package/app/app/api/sync/route.ts +36 -13
  327. package/app/app/global-error.tsx +3 -3
  328. package/app/app/globals.css +29 -3
  329. package/app/app/inbox/history/page.tsx +250 -0
  330. package/app/app/layout.tsx +5 -11
  331. package/app/app/login/page.tsx +1 -1
  332. package/app/app/page.tsx +3 -3
  333. package/app/app/view/[...path]/ViewPageClient.tsx +15 -10
  334. package/app/app/view/[...path]/not-found.tsx +1 -1
  335. package/app/app/view/[...path]/page.tsx +32 -1
  336. package/app/app/wiki/page.tsx +58 -0
  337. package/app/components/ActivityBar.tsx +9 -9
  338. package/app/components/AskFab.tsx +1 -1
  339. package/app/components/Backlinks.tsx +1 -1
  340. package/app/components/Breadcrumb.tsx +1 -1
  341. package/app/components/CreateSpaceModal.tsx +1 -1
  342. package/app/components/DirView.tsx +2 -2
  343. package/app/components/EchoSpotlight.tsx +14 -10
  344. package/app/components/Editor.tsx +1 -1
  345. package/app/components/ExportModal.tsx +3 -3
  346. package/app/components/FileTree.tsx +6 -11
  347. package/app/components/GuideCard.tsx +1 -1
  348. package/app/components/HomeContent.tsx +50 -39
  349. package/app/components/ImportModal.tsx +1 -2
  350. package/app/components/KeyboardShortcuts.tsx +1 -1
  351. package/app/components/MarkdownEditor.tsx +1 -1
  352. package/app/components/OnboardingView.tsx +2 -2
  353. package/app/components/OrganizeToast.tsx +3 -1
  354. package/app/components/Panel.tsx +27 -6
  355. package/app/components/Sidebar.tsx +1 -1
  356. package/app/components/SidebarLayout.tsx +30 -7
  357. package/app/components/SystemPulse.tsx +16 -16
  358. package/app/components/TrashPageClient.tsx +8 -6
  359. package/app/components/UpdateOverlay.tsx +1 -1
  360. package/app/components/WikiHomeContent.tsx +273 -0
  361. package/app/components/agents/AgentDetailContent.tsx +5 -5
  362. package/app/components/agents/AgentsContentPage.tsx +14 -3
  363. package/app/components/agents/AgentsOverviewSection.tsx +18 -92
  364. package/app/components/agents/AgentsPanelA2aTab.tsx +67 -66
  365. package/app/components/agents/AgentsPrimitives.tsx +1 -1
  366. package/app/components/agents/RecentActivityFeed.tsx +6 -6
  367. package/app/components/agents/SkillDetailPopover.tsx +1 -1
  368. package/app/components/agents/agents-content-model.ts +4 -1
  369. package/app/components/ask/AskHeader.tsx +1 -1
  370. package/app/components/changes/ChangesContentPage.tsx +10 -6
  371. package/app/components/echo/EchoHero.tsx +1 -1
  372. package/app/components/echo/EchoPageSections.tsx +1 -1
  373. package/app/components/explore/ExploreContent.tsx +1 -1
  374. package/app/components/explore/UseCaseCard.tsx +1 -1
  375. package/app/components/help/HelpContent.tsx +3 -3
  376. package/app/components/home/InboxSection.tsx +262 -54
  377. package/app/components/panels/AgentsPanel.tsx +4 -3
  378. package/app/components/panels/AgentsPanelAgentDetail.tsx +1 -1
  379. package/app/components/panels/AgentsPanelHubNav.tsx +10 -6
  380. package/app/components/panels/PanelHeader.tsx +1 -1
  381. package/app/components/renderers/audio/AudioRenderer.tsx +79 -0
  382. package/app/components/renderers/audio/manifest.ts +17 -0
  383. package/app/components/renderers/image/ImageRenderer.tsx +203 -0
  384. package/app/components/renderers/image/manifest.ts +17 -0
  385. package/app/components/renderers/pdf/PdfRenderer.tsx +57 -0
  386. package/app/components/renderers/pdf/manifest.ts +15 -0
  387. package/app/components/renderers/video/VideoRenderer.tsx +91 -0
  388. package/app/components/renderers/video/manifest.ts +17 -0
  389. package/app/components/settings/McpTab.tsx +154 -28
  390. package/app/components/settings/PluginsTab.tsx +1 -1
  391. package/app/components/settings/SettingsContent.tsx +41 -7
  392. package/app/components/settings/UpdateTab.tsx +18 -2
  393. package/app/components/settings/types.ts +7 -1
  394. package/app/components/setup/index.tsx +4 -3
  395. package/app/components/walkthrough/WalkthroughOverlay.tsx +1 -1
  396. package/app/components/walkthrough/WalkthroughTooltip.tsx +1 -1
  397. package/app/hooks/useAiOrganize.ts +14 -1
  398. package/app/lib/core/inbox.ts +131 -2
  399. package/app/lib/core/pdf-text.ts +28 -0
  400. package/app/lib/core/search-index.ts +29 -5
  401. package/app/lib/core/tree.ts +6 -1
  402. package/app/lib/fs.ts +32 -4
  403. package/app/lib/i18n/modules/ai-chat.ts +34 -0
  404. package/app/lib/i18n/modules/knowledge.ts +30 -0
  405. package/app/lib/i18n/modules/navigation.ts +4 -2
  406. package/app/lib/i18n/modules/panels.ts +22 -4
  407. package/app/lib/i18n/modules/settings.ts +26 -0
  408. package/app/lib/organize-history.ts +6 -0
  409. package/app/lib/renderers/index.ts +5 -1
  410. package/app/lib/settings.ts +28 -0
  411. package/bin/commands/doctor.js +12 -6
  412. package/bin/commands/file.js +7 -4
  413. package/bin/commands/logs.js +39 -4
  414. package/bin/commands/onboard.js +1 -1
  415. package/bin/commands/open.js +6 -1
  416. package/bin/commands/space.js +7 -4
  417. package/bin/commands/update.js +8 -18
  418. package/bin/lib/build.js +19 -8
  419. package/bin/lib/cli-shim.js +67 -2
  420. package/bin/lib/config.js +4 -5
  421. package/bin/lib/gateway.js +10 -23
  422. package/bin/lib/jsonc.js +7 -2
  423. package/bin/lib/mcp-agents.js +26 -5
  424. package/bin/lib/path-expand.js +6 -3
  425. package/bin/lib/port.js +5 -1
  426. package/bin/lib/stop.js +72 -51
  427. package/bin/lib/sync.js +1 -1
  428. package/package.json +1 -1
  429. package/scripts/setup.js +7 -5
  430. package/_standalone/.next/server/chunks/3436.js +0 -52
  431. package/_standalone/.next/server/chunks/5648.js +0 -2
  432. package/_standalone/.next/server/chunks/8408.js +0 -219
  433. package/_standalone/.next/static/W-wLgvhPtPJ5Psq9V4i3M/_buildManifest.js +0 -1
  434. package/_standalone/.next/static/chunks/1053-17786066ecd6f216.js +0 -29
  435. package/_standalone/.next/static/chunks/1814.72f7fe7c61e2b647.js +0 -1
  436. package/_standalone/.next/static/chunks/362.4c226d7887d5f696.js +0 -1
  437. package/_standalone/.next/static/chunks/6357-c645842834c0d4cd.js +0 -1
  438. package/_standalone/.next/static/chunks/6981-3d7dcac2d12a5670.js +0 -1
  439. package/_standalone/.next/static/chunks/7035-032641fb6f4e07b2.js +0 -1
  440. package/_standalone/.next/static/chunks/7144-5febf62f1a79fe64.js +0 -1
  441. package/_standalone/.next/static/chunks/9602-423291fdb36396d1.js +0 -1
  442. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-074d6aafc2606561.js +0 -1
  443. package/_standalone/.next/static/chunks/app/agents/page-710d8c80fa86e93e.js +0 -5
  444. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-b07a5983e85bc5e3.js +0 -1
  445. package/_standalone/.next/static/chunks/app/api/a2a/route-b07a5983e85bc5e3.js +0 -1
  446. package/_standalone/.next/static/chunks/app/api/acp/config/route-b07a5983e85bc5e3.js +0 -1
  447. package/_standalone/.next/static/chunks/app/api/acp/detect/route-b07a5983e85bc5e3.js +0 -1
  448. package/_standalone/.next/static/chunks/app/api/acp/install/route-b07a5983e85bc5e3.js +0 -1
  449. package/_standalone/.next/static/chunks/app/api/acp/registry/route-b07a5983e85bc5e3.js +0 -1
  450. package/_standalone/.next/static/chunks/app/api/acp/session/route-b07a5983e85bc5e3.js +0 -1
  451. package/_standalone/.next/static/chunks/app/api/agent-activity/route-b07a5983e85bc5e3.js +0 -1
  452. package/_standalone/.next/static/chunks/app/api/ask/route-b07a5983e85bc5e3.js +0 -1
  453. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-b07a5983e85bc5e3.js +0 -1
  454. package/_standalone/.next/static/chunks/app/api/auth/route-b07a5983e85bc5e3.js +0 -1
  455. package/_standalone/.next/static/chunks/app/api/backlinks/route-b07a5983e85bc5e3.js +0 -1
  456. package/_standalone/.next/static/chunks/app/api/bootstrap/route-b07a5983e85bc5e3.js +0 -1
  457. package/_standalone/.next/static/chunks/app/api/changes/route-b07a5983e85bc5e3.js +0 -1
  458. package/_standalone/.next/static/chunks/app/api/export/route-b07a5983e85bc5e3.js +0 -1
  459. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-b07a5983e85bc5e3.js +0 -1
  460. package/_standalone/.next/static/chunks/app/api/file/import/route-b07a5983e85bc5e3.js +0 -1
  461. package/_standalone/.next/static/chunks/app/api/file/route-b07a5983e85bc5e3.js +0 -1
  462. package/_standalone/.next/static/chunks/app/api/files/route-b07a5983e85bc5e3.js +0 -1
  463. package/_standalone/.next/static/chunks/app/api/git/route-b07a5983e85bc5e3.js +0 -1
  464. package/_standalone/.next/static/chunks/app/api/graph/route-b07a5983e85bc5e3.js +0 -1
  465. package/_standalone/.next/static/chunks/app/api/health/route-b07a5983e85bc5e3.js +0 -1
  466. package/_standalone/.next/static/chunks/app/api/inbox/route-b07a5983e85bc5e3.js +0 -1
  467. package/_standalone/.next/static/chunks/app/api/init/route-b07a5983e85bc5e3.js +0 -1
  468. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-b07a5983e85bc5e3.js +0 -1
  469. package/_standalone/.next/static/chunks/app/api/mcp/install/route-b07a5983e85bc5e3.js +0 -1
  470. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-b07a5983e85bc5e3.js +0 -1
  471. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-b07a5983e85bc5e3.js +0 -1
  472. package/_standalone/.next/static/chunks/app/api/mcp/status/route-b07a5983e85bc5e3.js +0 -1
  473. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-b07a5983e85bc5e3.js +0 -1
  474. package/_standalone/.next/static/chunks/app/api/monitoring/route-b07a5983e85bc5e3.js +0 -1
  475. package/_standalone/.next/static/chunks/app/api/recent-files/route-b07a5983e85bc5e3.js +0 -1
  476. package/_standalone/.next/static/chunks/app/api/restart/route-b07a5983e85bc5e3.js +0 -1
  477. package/_standalone/.next/static/chunks/app/api/search/route-b07a5983e85bc5e3.js +0 -1
  478. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-b07a5983e85bc5e3.js +0 -1
  479. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-b07a5983e85bc5e3.js +0 -1
  480. package/_standalone/.next/static/chunks/app/api/settings/route-b07a5983e85bc5e3.js +0 -1
  481. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-b07a5983e85bc5e3.js +0 -1
  482. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-b07a5983e85bc5e3.js +0 -1
  483. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-b07a5983e85bc5e3.js +0 -1
  484. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-b07a5983e85bc5e3.js +0 -1
  485. package/_standalone/.next/static/chunks/app/api/setup/ls/route-b07a5983e85bc5e3.js +0 -1
  486. package/_standalone/.next/static/chunks/app/api/setup/route-b07a5983e85bc5e3.js +0 -1
  487. package/_standalone/.next/static/chunks/app/api/skills/route-b07a5983e85bc5e3.js +0 -1
  488. package/_standalone/.next/static/chunks/app/api/sync/route-b07a5983e85bc5e3.js +0 -1
  489. package/_standalone/.next/static/chunks/app/api/tree-version/route-b07a5983e85bc5e3.js +0 -1
  490. package/_standalone/.next/static/chunks/app/api/uninstall/route-b07a5983e85bc5e3.js +0 -1
  491. package/_standalone/.next/static/chunks/app/api/update/route-b07a5983e85bc5e3.js +0 -1
  492. package/_standalone/.next/static/chunks/app/api/update-check/route-b07a5983e85bc5e3.js +0 -1
  493. package/_standalone/.next/static/chunks/app/api/update-status/route-b07a5983e85bc5e3.js +0 -1
  494. package/_standalone/.next/static/chunks/app/api/workflows/route-b07a5983e85bc5e3.js +0 -1
  495. package/_standalone/.next/static/chunks/app/changes/page-350992cf5091bc5b.js +0 -1
  496. package/_standalone/.next/static/chunks/app/echo/page-b07a5983e85bc5e3.js +0 -1
  497. package/_standalone/.next/static/chunks/app/global-error-e1ad0e18236ba26c.js +0 -1
  498. package/_standalone/.next/static/chunks/app/help/page-2325d25b6846ca07.js +0 -1
  499. package/_standalone/.next/static/chunks/app/layout-e5d2fb384207d821.js +0 -186
  500. package/_standalone/.next/static/chunks/app/loading-b07a5983e85bc5e3.js +0 -1
  501. package/_standalone/.next/static/chunks/app/page-54edd045d3448df5.js +0 -7
  502. package/_standalone/.next/static/chunks/app/trash/page-6372bb3f5463affa.js +0 -1
  503. package/_standalone/.next/static/chunks/app/view/[...path]/loading-b07a5983e85bc5e3.js +0 -1
  504. package/_standalone/.next/static/chunks/app/view/[...path]/not-found-61474670d6bb6116.js +0 -1
  505. package/_standalone/.next/static/chunks/app/view/[...path]/page-f3d1d87190dcfe28.js +0 -12
  506. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-b07a5983e85bc5e3.js +0 -1
  507. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-b07a5983e85bc5e3.js +0 -1
  508. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-b07a5983e85bc5e3.js +0 -1
  509. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-b07a5983e85bc5e3.js +0 -1
  510. package/_standalone/.next/static/css/bbf51803eade6c50.css +0 -31
  511. package/_standalone/.next/static/css/ef1151f74f00d91a.css +0 -1
  512. /package/_standalone/.next/static/{W-wLgvhPtPJ5Psq9V4i3M → QXZErVsiRQxfqUnWMUsH6}/_ssgManifest.js +0 -0
@@ -0,0 +1,203 @@
1
+ 'use client';
2
+
3
+ import { useState, useCallback, useRef, useEffect } from 'react';
4
+ import type { RendererContext } from '@/lib/renderers/registry';
5
+
6
+ /** Zoom presets — "fit" means object-fit: contain */
7
+ type ZoomMode = 'fit' | number;
8
+
9
+ const ZOOM_STEPS = [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4];
10
+
11
+ function formatBytes(bytes: number): string {
12
+ if (bytes < 1024) return `${bytes} B`;
13
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
14
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
15
+ }
16
+
17
+ /**
18
+ * Image Renderer — professional image viewer with:
19
+ * - Fit-to-view / actual-size toggle
20
+ * - Zoom in/out with presets
21
+ * - Checkerboard background for transparent images
22
+ * - Natural dimensions + file size display
23
+ * - Loading / error states with retry
24
+ */
25
+ export function ImageRenderer({ filePath }: RendererContext) {
26
+ const src = `/api/file/raw?path=${encodeURIComponent(filePath)}`;
27
+ const fileName = filePath.split('/').pop() ?? 'image';
28
+ const ext = fileName.split('.').pop()?.toLowerCase() ?? '';
29
+ const isTransparent = ['png', 'svg', 'webp', 'ico', 'gif'].includes(ext);
30
+
31
+ const [loading, setLoading] = useState(true);
32
+ const [error, setError] = useState(false);
33
+ const [retryKey, setRetryKey] = useState(0);
34
+ const [zoom, setZoom] = useState<ZoomMode>('fit');
35
+ const [naturalSize, setNaturalSize] = useState<{ w: number; h: number } | null>(null);
36
+ const [fileSize, setFileSize] = useState<number | null>(null);
37
+ const imgRef = useRef<HTMLImageElement>(null);
38
+ const containerRef = useRef<HTMLDivElement>(null);
39
+
40
+ const handleLoad = useCallback(() => {
41
+ setLoading(false);
42
+ const img = imgRef.current;
43
+ if (img) {
44
+ setNaturalSize({ w: img.naturalWidth, h: img.naturalHeight });
45
+ }
46
+ }, []);
47
+
48
+ const handleError = useCallback(() => {
49
+ setLoading(false);
50
+ setError(true);
51
+ }, []);
52
+
53
+ const handleRetry = useCallback(() => {
54
+ setError(false);
55
+ setLoading(true);
56
+ setRetryKey(k => k + 1);
57
+ }, []);
58
+
59
+ // Fetch file size — only once after image loads successfully
60
+ useEffect(() => {
61
+ if (loading || error || fileSize !== null) return;
62
+ fetch(src, { method: 'HEAD' })
63
+ .then(res => {
64
+ const cl = res.headers.get('Content-Length');
65
+ if (cl) setFileSize(parseInt(cl, 10));
66
+ })
67
+ .catch(() => {});
68
+ }, [src, loading, error, fileSize]);
69
+
70
+ const zoomIn = useCallback(() => {
71
+ setZoom(prev => {
72
+ const current = prev === 'fit' ? 1 : prev;
73
+ const next = ZOOM_STEPS.find(s => s > current);
74
+ return next ?? current;
75
+ });
76
+ }, []);
77
+
78
+ const zoomOut = useCallback(() => {
79
+ setZoom(prev => {
80
+ const current = prev === 'fit' ? 1 : prev;
81
+ const next = [...ZOOM_STEPS].reverse().find(s => s < current);
82
+ return next ?? current;
83
+ });
84
+ }, []);
85
+
86
+ const toggleFit = useCallback(() => {
87
+ setZoom(prev => prev === 'fit' ? 1 : 'fit');
88
+ }, []);
89
+
90
+ // Keyboard shortcuts — only active when container is focused or page body is active
91
+ useEffect(() => {
92
+ const container = containerRef.current;
93
+ if (!container) return;
94
+
95
+ const handler = (e: KeyboardEvent) => {
96
+ if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return;
97
+ // Only respond when the image viewer area has focus or body is active
98
+ if (document.activeElement !== document.body && !container.contains(document.activeElement)) return;
99
+ if (e.key === '+' || e.key === '=') { e.preventDefault(); zoomIn(); }
100
+ if (e.key === '-') { e.preventDefault(); zoomOut(); }
101
+ if (e.key === '0') { e.preventDefault(); setZoom('fit'); }
102
+ if (e.key === '1') { e.preventDefault(); setZoom(1); }
103
+ };
104
+ window.addEventListener('keydown', handler);
105
+ return () => window.removeEventListener('keydown', handler);
106
+ }, [zoomIn, zoomOut]);
107
+
108
+ const zoomPercent = zoom === 'fit' ? 'Fit' : `${Math.round(zoom * 100)}%`;
109
+ // Only use pixel dimensions when we know the natural size (avoids layout jump)
110
+ const zoomStyle = zoom === 'fit'
111
+ ? { maxWidth: '100%', maxHeight: '70vh', objectFit: 'contain' as const }
112
+ : naturalSize
113
+ ? { width: naturalSize.w * zoom, height: 'auto' }
114
+ : { maxWidth: '100%', maxHeight: '70vh', objectFit: 'contain' as const }; // fallback to fit while loading
115
+
116
+ return (
117
+ <div className="w-full flex flex-col gap-0">
118
+ {/* Toolbar */}
119
+ <div className="flex items-center justify-between px-3 py-2 border-b border-border text-xs text-[var(--text-secondary)]">
120
+ <div className="flex items-center gap-3">
121
+ {naturalSize && (
122
+ <span>{naturalSize.w} x {naturalSize.h}</span>
123
+ )}
124
+ {fileSize !== null && (
125
+ <span>{formatBytes(fileSize)}</span>
126
+ )}
127
+ <span className="uppercase opacity-60">{ext}</span>
128
+ </div>
129
+ <div className="flex items-center gap-1">
130
+ <button
131
+ onClick={zoomOut}
132
+ disabled={!naturalSize}
133
+ className="px-2 py-1 rounded hover:bg-[var(--bg-hover)] transition-colors disabled:opacity-30"
134
+ title="Zoom out (-)"
135
+ >
136
+ -
137
+ </button>
138
+ <button
139
+ onClick={toggleFit}
140
+ disabled={!naturalSize}
141
+ className="px-2 py-1 rounded hover:bg-[var(--bg-hover)] transition-colors min-w-[48px] text-center disabled:opacity-30"
142
+ title={zoom === 'fit' ? 'Actual size (1)' : 'Fit to view (0)'}
143
+ >
144
+ {zoomPercent}
145
+ </button>
146
+ <button
147
+ onClick={zoomIn}
148
+ disabled={!naturalSize}
149
+ className="px-2 py-1 rounded hover:bg-[var(--bg-hover)] transition-colors disabled:opacity-30"
150
+ title="Zoom in (+)"
151
+ >
152
+ +
153
+ </button>
154
+ </div>
155
+ </div>
156
+
157
+ {/* Image area */}
158
+ <div
159
+ ref={containerRef}
160
+ tabIndex={-1}
161
+ className={`relative flex-1 min-h-[70vh] overflow-auto flex items-center justify-center outline-none ${
162
+ isTransparent ? 'bg-checkerboard' : 'bg-[var(--bg-secondary)]'
163
+ }`}
164
+ >
165
+ {loading && !error && (
166
+ <div className="absolute inset-0 flex items-center justify-center z-10">
167
+ <span className="text-sm text-[var(--text-tertiary)] animate-pulse">
168
+ Loading...
169
+ </span>
170
+ </div>
171
+ )}
172
+ {error && (
173
+ <div className="absolute inset-0 flex flex-col items-center justify-center z-10 gap-2">
174
+ <span className="text-sm text-[var(--text-secondary)]">
175
+ Failed to load image
176
+ </span>
177
+ <button
178
+ onClick={handleRetry}
179
+ className="text-xs px-3 py-1.5 rounded-md bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] transition-colors"
180
+ >
181
+ Retry
182
+ </button>
183
+ </div>
184
+ )}
185
+ {/* eslint-disable-next-line @next/next/no-img-element */}
186
+ <img
187
+ key={retryKey}
188
+ ref={imgRef}
189
+ src={src}
190
+ alt={fileName}
191
+ onLoad={handleLoad}
192
+ onError={handleError}
193
+ draggable={false}
194
+ className="select-none"
195
+ style={{
196
+ display: error ? 'none' : 'block',
197
+ ...zoomStyle,
198
+ }}
199
+ />
200
+ </div>
201
+ </div>
202
+ );
203
+ }
@@ -0,0 +1,57 @@
1
+ 'use client';
2
+
3
+ import { useState, useCallback } from 'react';
4
+ import type { RendererContext } from '@/lib/renderers/registry';
5
+
6
+ /**
7
+ * PDF Renderer — embeds the browser's native PDF viewer via iframe.
8
+ * Fetches the PDF binary from /api/file/raw and displays inline.
9
+ * Read-only: no editing capability (PDF editing is out of scope).
10
+ */
11
+ export function PdfRenderer({ filePath }: RendererContext) {
12
+ const src = `/api/file/raw?path=${encodeURIComponent(filePath)}`;
13
+ const [loading, setLoading] = useState(true);
14
+ const [error, setError] = useState(false);
15
+ // Increment key to force iframe remount on retry
16
+ const [retryKey, setRetryKey] = useState(0);
17
+
18
+ const handleRetry = useCallback(() => {
19
+ setError(false);
20
+ setLoading(true);
21
+ setRetryKey(k => k + 1);
22
+ }, []);
23
+
24
+ return (
25
+ <div className="w-full h-full min-h-[80vh] flex flex-col relative">
26
+ {loading && !error && (
27
+ <div className="absolute inset-0 flex items-center justify-center bg-[var(--bg-secondary)] rounded-lg z-10">
28
+ <span className="text-sm text-[var(--text-tertiary)] animate-pulse">
29
+ Loading PDF...
30
+ </span>
31
+ </div>
32
+ )}
33
+ {error && (
34
+ <div className="absolute inset-0 flex flex-col items-center justify-center bg-[var(--bg-secondary)] rounded-lg z-10 gap-2">
35
+ <span className="text-sm text-[var(--text-secondary)]">
36
+ Failed to load PDF
37
+ </span>
38
+ <button
39
+ onClick={handleRetry}
40
+ className="text-xs px-3 py-1.5 rounded-md bg-[var(--bg-tertiary)] hover:bg-[var(--bg-hover)] transition-colors"
41
+ >
42
+ Retry
43
+ </button>
44
+ </div>
45
+ )}
46
+ <iframe
47
+ key={retryKey}
48
+ src={src}
49
+ className="w-full flex-1 min-h-[80vh] border-0 rounded-lg bg-[var(--bg-secondary)]"
50
+ title={filePath.split('/').pop() ?? 'PDF'}
51
+ onLoad={() => setLoading(false)}
52
+ onError={() => { setLoading(false); setError(true); }}
53
+ style={{ display: error ? 'none' : 'block' }}
54
+ />
55
+ </div>
56
+ );
57
+ }
@@ -0,0 +1,91 @@
1
+ 'use client';
2
+
3
+ import { useState, useCallback, useRef, useEffect } from 'react';
4
+ import type { RendererContext } from '@/lib/renderers/registry';
5
+
6
+ function formatBytes(bytes: number): string {
7
+ if (bytes < 1024) return `${bytes} B`;
8
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
9
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
10
+ }
11
+
12
+ /**
13
+ * Video Renderer — native HTML5 video player with file info bar.
14
+ * Uses browser built-in controls (play/pause, seek, volume, fullscreen, PiP).
15
+ * Supports Range requests for seeking without downloading entire file.
16
+ */
17
+ export function VideoRenderer({ filePath }: RendererContext) {
18
+ const src = `/api/file/raw?path=${encodeURIComponent(filePath)}`;
19
+ const fileName = filePath.split('/').pop() ?? 'video';
20
+ const ext = fileName.split('.').pop()?.toLowerCase() ?? '';
21
+
22
+ const [error, setError] = useState(false);
23
+ const [retryKey, setRetryKey] = useState(0);
24
+ const [fileSize, setFileSize] = useState<number | null>(null);
25
+ const [resolution, setResolution] = useState<{ w: number; h: number } | null>(null);
26
+ const videoRef = useRef<HTMLVideoElement>(null);
27
+
28
+ useEffect(() => {
29
+ fetch(src, { method: 'HEAD' })
30
+ .then(res => {
31
+ const cl = res.headers.get('Content-Length');
32
+ if (cl) setFileSize(parseInt(cl, 10));
33
+ })
34
+ .catch(() => {});
35
+ }, [src]);
36
+
37
+ const handleLoadedMetadata = useCallback(() => {
38
+ const video = videoRef.current;
39
+ if (video) {
40
+ setResolution({ w: video.videoWidth, h: video.videoHeight });
41
+ }
42
+ }, []);
43
+
44
+ const handleRetry = useCallback(() => {
45
+ setError(false);
46
+ setRetryKey(k => k + 1);
47
+ }, []);
48
+
49
+ return (
50
+ <div className="w-full flex flex-col gap-0">
51
+ {/* Info bar */}
52
+ <div className="flex items-center gap-3 px-3 py-2 border-b border-border text-xs text-[var(--text-secondary)]">
53
+ {resolution && (
54
+ <span>{resolution.w} x {resolution.h}</span>
55
+ )}
56
+ {fileSize !== null && (
57
+ <span>{formatBytes(fileSize)}</span>
58
+ )}
59
+ <span className="uppercase opacity-60">{ext}</span>
60
+ </div>
61
+
62
+ {/* Player area */}
63
+ <div className="flex-1 min-h-[50vh] flex items-center justify-center bg-black rounded-b-lg overflow-hidden">
64
+ {error ? (
65
+ <div className="flex flex-col items-center gap-2">
66
+ <span className="text-sm text-neutral-400">Failed to load video</span>
67
+ <button
68
+ onClick={handleRetry}
69
+ className="text-xs px-3 py-1.5 rounded-md bg-neutral-800 hover:bg-neutral-700 text-neutral-200 transition-colors"
70
+ >
71
+ Retry
72
+ </button>
73
+ </div>
74
+ ) : (
75
+ /* eslint-disable-next-line jsx-a11y/media-has-caption */
76
+ <video
77
+ key={retryKey}
78
+ ref={videoRef}
79
+ controls
80
+ preload="metadata"
81
+ className="max-w-full max-h-[70vh]"
82
+ onLoadedMetadata={handleLoadedMetadata}
83
+ onError={() => setError(true)}
84
+ >
85
+ <source src={src} />
86
+ </video>
87
+ )}
88
+ </div>
89
+ </div>
90
+ );
91
+ }
@@ -7,7 +7,7 @@ import { copyToClipboard } from '@/lib/clipboard';
7
7
  import { apiFetch } from '@/lib/api';
8
8
  import CustomSelect from '@/components/CustomSelect';
9
9
  import type { SelectItem } from '@/components/CustomSelect';
10
- import type { McpTabProps, McpStatus, AgentInfo } from './types';
10
+ import type { McpTabProps, McpStatus, AgentInfo, ConnectionMode } from './types';
11
11
  import AgentInstall from './McpAgentInstall';
12
12
  import SkillsSection from './McpSkillsSection';
13
13
 
@@ -20,8 +20,13 @@ export function McpTab({ t }: McpTabProps) {
20
20
  const [mode, setMode] = useState<'cli' | 'mcp'>('cli');
21
21
  const [restarting, setRestarting] = useState(false);
22
22
  const [selectedAgent, setSelectedAgent] = useState('');
23
+ const [savingMode, setSavingMode] = useState(false);
23
24
  const restartPollRef = useRef<ReturnType<typeof setInterval>>(undefined);
24
25
 
26
+ // Derive mcpEnabled from server state
27
+ const serverConnectionMode = mcp?.status?.connectionMode;
28
+ const mcpEnabled = serverConnectionMode?.mcp ?? false;
29
+
25
30
  useEffect(() => () => clearInterval(restartPollRef.current), []);
26
31
 
27
32
  if (!mcp || mcp.loading) {
@@ -42,6 +47,26 @@ export function McpTab({ t }: McpTabProps) {
42
47
  const mindosEnabled = mcp.skills?.find(s => s.name === 'mindos')?.enabled ?? true;
43
48
  const activeSkillName = mindosEnabled ? 'mindos' : 'mindos-zh';
44
49
 
50
+ const handleToggleMcp = async (enabled: boolean) => {
51
+ setSavingMode(true);
52
+ try {
53
+ await apiFetch('/api/settings', {
54
+ method: 'POST',
55
+ headers: { 'Content-Type': 'application/json' },
56
+ body: JSON.stringify({
57
+ connectionMode: { cli: true, mcp: enabled },
58
+ }),
59
+ });
60
+ await mcp.refresh();
61
+ // Switch view to MCP tab when enabling
62
+ if (enabled) setMode('mcp');
63
+ } catch {
64
+ toast.error('Failed to toggle connection mode');
65
+ } finally {
66
+ setSavingMode(false);
67
+ }
68
+ };
69
+
45
70
  const handleRestart = async () => {
46
71
  setRestarting(true);
47
72
  try {
@@ -72,6 +97,15 @@ export function McpTab({ t }: McpTabProps) {
72
97
 
73
98
  return (
74
99
  <div className="space-y-6">
100
+ {/* 0. Connection Mode Toggle */}
101
+ <ConnectionModeCard
102
+ mcpEnabled={mcpEnabled}
103
+ onToggle={handleToggleMcp}
104
+ saving={savingMode}
105
+ mcpRunning={mcp.status?.running ?? false}
106
+ m={m}
107
+ />
108
+
75
109
  {/* 1. Auth Token */}
76
110
  <AuthTokenCard status={mcp.status} m={m} />
77
111
 
@@ -91,6 +125,7 @@ export function McpTab({ t }: McpTabProps) {
91
125
  onRestart={handleRestart}
92
126
  onRefresh={mcp.refresh}
93
127
  activeSkillName={activeSkillName}
128
+ mcpEnabled={mcpEnabled}
94
129
  m={m}
95
130
  t={t}
96
131
  />
@@ -114,6 +149,83 @@ export function McpTab({ t }: McpTabProps) {
114
149
  );
115
150
  }
116
151
 
152
+ /* ── Connection Mode Card ── */
153
+
154
+ function ConnectionModeCard({ mcpEnabled, onToggle, saving, mcpRunning, m }: {
155
+ mcpEnabled: boolean;
156
+ onToggle: (enabled: boolean) => void;
157
+ saving: boolean;
158
+ mcpRunning: boolean;
159
+ m: Record<string, any> | undefined;
160
+ }) {
161
+ return (
162
+ <div className="rounded-xl border border-border bg-card overflow-hidden">
163
+ <div className="flex items-center gap-2.5 px-4 pt-4 pb-3">
164
+ <div className="w-7 h-7 rounded-lg bg-[var(--amber-subtle)] flex items-center justify-center shrink-0">
165
+ <Plug size={14} className="text-[var(--amber)]" />
166
+ </div>
167
+ <div className="flex-1 min-w-0">
168
+ <h3 className="text-sm font-semibold text-foreground">{m?.modeCardTitle ?? 'Connection Mode'}</h3>
169
+ <p className="text-2xs text-muted-foreground">{m?.modeCardDesc ?? 'Choose how agents connect to MindOS.'}</p>
170
+ </div>
171
+ </div>
172
+ <div className="px-4 pb-4 space-y-2">
173
+ {/* CLI - always on */}
174
+ <div className="flex items-center gap-3 px-3 py-2.5 rounded-lg bg-muted/30 border border-border/50">
175
+ <input type="checkbox" checked disabled className="w-3.5 h-3.5 rounded accent-[var(--amber)]" />
176
+ <div className="flex-1 min-w-0">
177
+ <div className="flex items-center gap-1.5">
178
+ <Terminal size={12} className="text-muted-foreground" />
179
+ <span className="text-xs font-semibold text-foreground">CLI</span>
180
+ <span className="text-2xs px-1.5 py-0.5 rounded-full bg-success/10 text-success font-medium leading-none">
181
+ {m?.alwaysOn ?? 'Always On'}
182
+ </span>
183
+ </div>
184
+ <p className="text-2xs text-muted-foreground mt-0.5">{m?.cliModeDesc ?? 'Claude Code, Gemini CLI, Codex, etc.'}</p>
185
+ </div>
186
+ </div>
187
+
188
+ {/* MCP - toggleable */}
189
+ <label className={`flex items-center gap-3 px-3 py-2.5 rounded-lg border cursor-pointer transition-colors ${
190
+ mcpEnabled
191
+ ? 'border-[var(--amber)]/40 bg-[var(--amber)]/[0.03]'
192
+ : 'border-border/50 bg-muted/30 hover:bg-muted/50'
193
+ }`}>
194
+ <input
195
+ type="checkbox"
196
+ checked={mcpEnabled}
197
+ disabled={saving}
198
+ onChange={(e) => onToggle(e.target.checked)}
199
+ className="w-3.5 h-3.5 rounded accent-[var(--amber)] cursor-pointer"
200
+ />
201
+ <div className="flex-1 min-w-0">
202
+ <div className="flex items-center gap-1.5">
203
+ <Plug size={12} className={mcpEnabled ? 'text-[var(--amber)]' : 'text-muted-foreground'} />
204
+ <span className="text-xs font-semibold text-foreground">MCP</span>
205
+ {mcpEnabled && (
206
+ <span className={`text-2xs px-1.5 py-0.5 rounded-full font-medium leading-none ${
207
+ mcpRunning ? 'bg-success/10 text-success' : 'bg-[var(--amber-subtle)] text-[var(--amber-text)]'
208
+ }`}>
209
+ {mcpRunning ? (m?.mcpRunning ?? 'Running') : (m?.mcpStopped ?? 'Stopped')}
210
+ </span>
211
+ )}
212
+ </div>
213
+ <p className="text-2xs text-muted-foreground mt-0.5">{m?.mcpModeDesc ?? 'Claude Desktop, Cursor, Windsurf, etc.'}</p>
214
+ </div>
215
+ {saving && <Loader2 size={14} className="animate-spin text-[var(--amber)] shrink-0" />}
216
+ </label>
217
+
218
+ {/* Hint text */}
219
+ <p className="text-2xs text-muted-foreground px-1 leading-relaxed">
220
+ {mcpEnabled
221
+ ? (m?.mcpEnabledHint ?? 'MCP mode enabled. Disable to simplify the interface if you only use CLI agents.')
222
+ : (m?.mcpDisabledHint ?? 'Enable MCP to connect Desktop clients like Claude Desktop or Cursor.')}
223
+ </p>
224
+ </div>
225
+ </div>
226
+ );
227
+ }
228
+
117
229
  /* ── Auth Token Card ── */
118
230
 
119
231
  function AuthTokenCard({ status, m }: {
@@ -195,7 +307,7 @@ function useCopyField() {
195
307
 
196
308
  /* ── Connect Card — header + CLI/MCP tabs + detected agents ── */
197
309
 
198
- function ConnectCard({ mode, onModeChange, status, agents, connectedAgents, detectedAgents, notFoundAgents, currentAgent, selectedAgent, onSelectAgent, restarting, onRestart, onRefresh, activeSkillName, m, t }: {
310
+ function ConnectCard({ mode, onModeChange, status, agents, connectedAgents, detectedAgents, notFoundAgents, currentAgent, selectedAgent, onSelectAgent, restarting, onRestart, onRefresh, activeSkillName, mcpEnabled, m, t }: {
199
311
  mode: 'cli' | 'mcp';
200
312
  onModeChange: (m: 'cli' | 'mcp') => void;
201
313
  status: McpStatus | null;
@@ -210,11 +322,15 @@ function ConnectCard({ mode, onModeChange, status, agents, connectedAgents, dete
210
322
  onRestart: () => void;
211
323
  onRefresh: () => void;
212
324
  activeSkillName: string;
325
+ mcpEnabled: boolean;
213
326
  m: Record<string, any> | undefined;
214
327
  t: McpTabProps['t'];
215
328
  }) {
216
329
  if (!status) return null;
217
330
 
331
+ // If MCP is disabled, force CLI view
332
+ const effectiveMode = mcpEnabled ? mode : 'cli';
333
+
218
334
  return (
219
335
  <div className="rounded-xl border border-border bg-card overflow-hidden">
220
336
  {/* Header */}
@@ -225,38 +341,48 @@ function ConnectCard({ mode, onModeChange, status, agents, connectedAgents, dete
225
341
  <h3 className="text-sm font-semibold text-foreground">{m?.connectionTitle ?? 'Connect Agents'}</h3>
226
342
  </div>
227
343
 
228
- {/* Tab switcher */}
229
- <div className="grid grid-cols-2 mx-4 mb-3 rounded-lg border border-border overflow-hidden">
230
- <button
231
- onClick={() => onModeChange('cli')}
232
- className={`flex flex-col items-start px-3 py-2.5 text-left transition-colors ${
233
- mode === 'cli' ? 'bg-muted' : 'hover:bg-muted/50'
234
- }`}
235
- >
344
+ {/* Tab switcher — only show both tabs when MCP is enabled */}
345
+ {mcpEnabled ? (
346
+ <div className="grid grid-cols-2 mx-4 mb-3 rounded-lg border border-border overflow-hidden">
347
+ <button
348
+ onClick={() => onModeChange('cli')}
349
+ className={`flex flex-col items-start px-3 py-2.5 text-left transition-colors ${
350
+ effectiveMode === 'cli' ? 'bg-muted' : 'hover:bg-muted/50'
351
+ }`}
352
+ >
353
+ <span className="flex items-center gap-1.5">
354
+ <Terminal size={12} className={effectiveMode === 'cli' ? 'text-[var(--amber)]' : 'text-muted-foreground'} />
355
+ <span className={`text-xs font-semibold ${effectiveMode === 'cli' ? 'text-foreground' : 'text-muted-foreground'}`}>CLI</span>
356
+ <span className="text-2xs px-1 py-0.5 rounded bg-[var(--amber-subtle)] text-[var(--amber-text)] font-medium leading-none">{m?.recommended ?? 'Recommended'}</span>
357
+ </span>
358
+ <span className="text-2xs text-muted-foreground mt-0.5">{m?.cliAgents ?? 'Claude Code · Gemini CLI · Codex'}</span>
359
+ </button>
360
+ <button
361
+ onClick={() => onModeChange('mcp')}
362
+ className={`flex flex-col items-start px-3 py-2.5 text-left transition-colors border-l border-border ${
363
+ effectiveMode === 'mcp' ? 'bg-muted' : 'hover:bg-muted/50'
364
+ }`}
365
+ >
366
+ <span className="flex items-center gap-1.5">
367
+ <Plug size={12} className={effectiveMode === 'mcp' ? 'text-foreground' : 'text-muted-foreground'} />
368
+ <span className={`text-xs font-semibold ${effectiveMode === 'mcp' ? 'text-foreground' : 'text-muted-foreground'}`}>MCP</span>
369
+ </span>
370
+ <span className="text-2xs text-muted-foreground mt-0.5">{m?.mcpAgents ?? 'Claude Desktop · Cursor'}</span>
371
+ </button>
372
+ </div>
373
+ ) : (
374
+ <div className="mx-4 mb-3 px-3 py-2 rounded-lg border border-border bg-muted/30">
236
375
  <span className="flex items-center gap-1.5">
237
- <Terminal size={12} className={mode === 'cli' ? 'text-[var(--amber)]' : 'text-muted-foreground'} />
238
- <span className={`text-xs font-semibold ${mode === 'cli' ? 'text-foreground' : 'text-muted-foreground'}`}>CLI</span>
376
+ <Terminal size={12} className="text-[var(--amber)]" />
377
+ <span className="text-xs font-semibold text-foreground">CLI</span>
239
378
  <span className="text-2xs px-1 py-0.5 rounded bg-[var(--amber-subtle)] text-[var(--amber-text)] font-medium leading-none">{m?.recommended ?? 'Recommended'}</span>
240
379
  </span>
241
- <span className="text-2xs text-muted-foreground mt-0.5">{m?.cliAgents ?? 'Claude Code · Gemini CLI · Codex'}</span>
242
- </button>
243
- <button
244
- onClick={() => onModeChange('mcp')}
245
- className={`flex flex-col items-start px-3 py-2.5 text-left transition-colors border-l border-border ${
246
- mode === 'mcp' ? 'bg-muted' : 'hover:bg-muted/50'
247
- }`}
248
- >
249
- <span className="flex items-center gap-1.5">
250
- <Plug size={12} className={mode === 'mcp' ? 'text-foreground' : 'text-muted-foreground'} />
251
- <span className={`text-xs font-semibold ${mode === 'mcp' ? 'text-foreground' : 'text-muted-foreground'}`}>MCP</span>
252
- </span>
253
- <span className="text-2xs text-muted-foreground mt-0.5">{m?.mcpAgents ?? 'Claude Desktop · Cursor'}</span>
254
- </button>
255
- </div>
380
+ </div>
381
+ )}
256
382
 
257
383
  {/* Tab content */}
258
384
  <div className="px-4 pb-4 space-y-4">
259
- {mode === 'cli' ? (
385
+ {effectiveMode === 'cli' ? (
260
386
  <CliGuide status={status} activeSkillName={activeSkillName} agents={agents} connectedAgents={connectedAgents} detectedAgents={detectedAgents} notFoundAgents={notFoundAgents} onRefresh={onRefresh} m={m} t={t} />
261
387
  ) : (
262
388
  <McpGuide
@@ -66,7 +66,7 @@ export function PluginsTab({ pluginStates, setPluginStates, t }: PluginsTabProps
66
66
  </div>
67
67
  )}
68
68
 
69
- <div className="flex items-center gap-2 text-xs text-muted-foreground border border-dashed border-border rounded-xl px-4 py-3">
69
+ <div className="flex items-center gap-2 text-xs text-muted-foreground border border-border/40 bg-card/30 rounded-xl px-4 py-3">
70
70
  <Puzzle size={13} className="shrink-0" />
71
71
  <span>{t.settings.plugins.comingSoon}</span>
72
72
  </div>