@geminilight/mindos 0.6.40 → 0.6.41

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 (287) 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 +18 -18
  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 +5 -1
  10. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  11. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/_standalone/.next/server/app/_global-error.html +2 -2
  13. package/_standalone/.next/server/app/_global-error.rsc +1 -1
  14. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  17. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  21. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  22. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  23. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  24. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  25. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  26. package/_standalone/.next/server/app/agents/page.js +2 -2
  27. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  28. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  29. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  31. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  32. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  35. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/ask/route.js +1 -1
  40. package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
  41. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  42. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  43. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  44. package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
  45. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  46. package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
  47. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  48. package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
  49. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  50. package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
  51. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  53. package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
  54. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  55. package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
  56. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  58. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  59. package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  60. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  61. package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
  62. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  63. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  64. package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
  65. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  66. package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
  67. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  68. package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
  69. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  70. package/_standalone/.next/server/app/api/mcp/install/route.js +1 -1
  71. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  72. package/_standalone/.next/server/app/api/mcp/install-skill/route.js.nft.json +1 -1
  73. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  74. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  75. package/_standalone/.next/server/app/api/mcp/status/route.js +1 -1
  76. package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
  77. package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
  78. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  79. package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
  80. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  81. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  82. package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  83. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  84. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  85. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  86. package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  87. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  88. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  89. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  91. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  92. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  93. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  94. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  96. package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
  97. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  98. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  99. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  100. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  102. package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
  103. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  104. package/_standalone/.next/server/app/changes/page.js +1 -1
  105. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  106. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  107. package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
  108. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  109. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  110. package/_standalone/.next/server/app/echo/page.js +1 -1
  111. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  112. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  113. package/_standalone/.next/server/app/explore/page.js +1 -1
  114. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  115. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  116. package/_standalone/.next/server/app/help/page.js +2 -2
  117. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  118. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  119. package/_standalone/.next/server/app/login/page.js +1 -1
  120. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  121. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  122. package/_standalone/.next/server/app/page.js +2 -2
  123. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  124. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  125. package/_standalone/.next/server/app/setup/page.js +2 -2
  126. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  127. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  128. package/_standalone/.next/server/app/trash/page.js +3 -3
  129. package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
  130. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  131. package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
  132. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  133. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  134. package/_standalone/.next/server/app-paths-manifest.json +18 -18
  135. package/_standalone/.next/server/chunks/1550.js +1 -1
  136. package/_standalone/.next/server/chunks/2190.js +11 -0
  137. package/_standalone/.next/server/chunks/{6365.js → 2536.js} +2 -2
  138. package/_standalone/.next/server/chunks/5648.js +2 -0
  139. package/_standalone/.next/server/chunks/8388.js +1 -1
  140. package/_standalone/.next/server/chunks/953.js +1 -1
  141. package/_standalone/.next/server/chunks/9539.js +219 -0
  142. package/_standalone/.next/server/middleware-build-manifest.js +1 -1
  143. package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  144. package/_standalone/.next/server/next-font-manifest.js +1 -1
  145. package/_standalone/.next/server/next-font-manifest.json +1 -1
  146. package/_standalone/.next/server/pages/500.html +2 -2
  147. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  148. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  149. package/_standalone/.next/static/chunks/1053-b70535785cc5aaee.js +29 -0
  150. package/_standalone/.next/static/chunks/{8663-de911d2d395622be.js → 1880-c2a9e76201841c86.js} +1 -1
  151. package/_standalone/.next/static/chunks/3637.0541ac2d0ea7de1f.js +1 -0
  152. package/_standalone/.next/static/chunks/4563-b2a2ce80aff845af.js +6 -0
  153. package/_standalone/.next/static/chunks/6981-3d7dcac2d12a5670.js +1 -0
  154. package/_standalone/.next/static/chunks/7144-5febf62f1a79fe64.js +1 -0
  155. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-773071a99c4daac2.js +1 -0
  156. package/_standalone/.next/static/chunks/app/agents/page-6102a884b2cb3cfe.js +5 -0
  157. package/_standalone/.next/static/chunks/app/help/page-2325d25b6846ca07.js +1 -0
  158. package/_standalone/.next/static/chunks/app/{layout-9378c1c8d3e5761b.js → layout-42cdbce19f404567.js} +34 -34
  159. package/_standalone/.next/static/chunks/app/{page-9bae420fbbdc5fff.js → page-8c9643b649e01735.js} +1 -1
  160. package/_standalone/.next/static/chunks/app/setup/page-d158b8cb533feb1e.js +1 -0
  161. package/_standalone/.next/static/chunks/app/trash/{page-b61ef2d5cd4f8d73.js → page-e9ab74ffeb96af41.js} +1 -1
  162. package/_standalone/.next/static/chunks/app/view/[...path]/page-764a69a1c8bd4eef.js +12 -0
  163. package/_standalone/.next/static/chunks/{webpack-c28c55d0a6021a6b.js → webpack-7b276daaa930d480.js} +1 -1
  164. package/_standalone/.next/static/css/bc9179074eaf65ae.css +1 -0
  165. package/_standalone/.next/trace +63 -63
  166. package/_standalone/__tests__/api/mcp-install.test.ts +23 -0
  167. package/_standalone/__tests__/cli/agent-routing.test.ts +232 -0
  168. package/_standalone/__tests__/cli/file-subcommands.test.ts +379 -0
  169. package/_standalone/__tests__/core/tools.test.ts +3 -6
  170. package/_standalone/components/FileTree.tsx +3 -2
  171. package/_standalone/components/MarkdownView.tsx +30 -15
  172. package/_standalone/components/RightAskPanel.tsx +36 -6
  173. package/_standalone/components/Sidebar.tsx +3 -3
  174. package/_standalone/components/agents/AgentsMcpSection.tsx +3 -0
  175. package/_standalone/components/settings/McpAgentInstall.tsx +94 -27
  176. package/_standalone/components/settings/McpSkillsSection.tsx +1 -1
  177. package/_standalone/components/settings/McpTab.tsx +484 -340
  178. package/_standalone/components/settings/SettingsContent.tsx +12 -6
  179. package/_standalone/components/settings/types.ts +3 -0
  180. package/_standalone/components/setup/StepAgents.tsx +113 -47
  181. package/_standalone/components/setup/StepReview.tsx +14 -27
  182. package/_standalone/components/setup/types.ts +6 -0
  183. package/_standalone/data/skills/mindos/SKILL.md +92 -92
  184. package/_standalone/data/skills/mindos/references/write-supplement.md +119 -0
  185. package/_standalone/data/skills/mindos-zh/SKILL.md +100 -104
  186. package/_standalone/data/skills/mindos-zh/references/write-supplement.md +119 -0
  187. package/_standalone/lib/i18n/modules/features.ts +4 -4
  188. package/_standalone/lib/i18n/modules/knowledge.ts +4 -0
  189. package/_standalone/lib/i18n/modules/onboarding.ts +40 -30
  190. package/_standalone/lib/i18n/modules/settings.ts +78 -6
  191. package/_standalone/lib/mcp-snippets.ts +5 -1
  192. package/_standalone/tsconfig.tsbuildinfo +1 -1
  193. package/app/app/api/ask/route.ts +3 -2
  194. package/app/app/api/mcp/install/route.ts +2 -1
  195. package/app/app/api/mcp/status/route.ts +14 -6
  196. package/app/app/view/[...path]/ViewPageClient.tsx +12 -27
  197. package/app/components/FileTree.tsx +3 -2
  198. package/app/components/MarkdownView.tsx +30 -15
  199. package/app/components/RightAskPanel.tsx +36 -6
  200. package/app/components/Sidebar.tsx +3 -3
  201. package/app/components/agents/AgentsMcpSection.tsx +3 -0
  202. package/app/components/help/HelpContent.tsx +1 -0
  203. package/app/components/settings/McpAgentInstall.tsx +94 -27
  204. package/app/components/settings/McpSkillsSection.tsx +1 -1
  205. package/app/components/settings/McpTab.tsx +484 -340
  206. package/app/components/settings/SettingsContent.tsx +12 -6
  207. package/app/components/settings/types.ts +3 -0
  208. package/app/components/setup/StepAgents.tsx +113 -47
  209. package/app/components/setup/StepReview.tsx +14 -27
  210. package/app/components/setup/index.tsx +12 -11
  211. package/app/components/setup/types.ts +6 -0
  212. package/app/data/skills/mindos/SKILL.md +92 -92
  213. package/app/data/skills/mindos/references/write-supplement.md +119 -0
  214. package/app/data/skills/mindos-zh/SKILL.md +100 -104
  215. package/app/data/skills/mindos-zh/references/write-supplement.md +119 -0
  216. package/app/lib/fs.ts +0 -6
  217. package/app/lib/i18n/modules/features.ts +4 -4
  218. package/app/lib/i18n/modules/knowledge.ts +4 -0
  219. package/app/lib/i18n/modules/onboarding.ts +40 -30
  220. package/app/lib/i18n/modules/settings.ts +78 -6
  221. package/app/lib/mcp-agents.ts +1 -2
  222. package/app/lib/mcp-snippets.ts +5 -1
  223. package/app/lib/renderers/index.ts +2 -1
  224. package/bin/cli.js +168 -1404
  225. package/bin/commands/agent.js +156 -20
  226. package/bin/commands/api.js +14 -11
  227. package/bin/commands/ask.js +79 -68
  228. package/bin/commands/build.js +26 -0
  229. package/bin/commands/config.js +170 -0
  230. package/bin/commands/dev.js +58 -0
  231. package/bin/commands/doctor.js +205 -0
  232. package/bin/commands/file.js +551 -36
  233. package/bin/commands/gateway.js +42 -0
  234. package/bin/commands/init-skills.js +56 -0
  235. package/bin/commands/logs.js +32 -0
  236. package/bin/commands/mcp-cmd.js +57 -0
  237. package/bin/commands/onboard.js +25 -0
  238. package/bin/commands/open.js +41 -0
  239. package/bin/commands/restart.js +48 -0
  240. package/bin/commands/search.js +16 -14
  241. package/bin/commands/space.js +96 -25
  242. package/bin/commands/start.js +262 -0
  243. package/bin/commands/status.js +2 -2
  244. package/bin/commands/stop.js +14 -0
  245. package/bin/commands/sync-cmd.js +134 -0
  246. package/bin/commands/token.js +98 -0
  247. package/bin/commands/uninstall.js +154 -0
  248. package/bin/commands/update.js +286 -0
  249. package/bin/lib/build.js +1 -1
  250. package/bin/lib/colors.js +8 -7
  251. package/bin/lib/command.js +37 -96
  252. package/bin/lib/config.js +5 -0
  253. package/bin/lib/csv.js +19 -0
  254. package/bin/lib/jsonc.js +12 -0
  255. package/bin/lib/markdown.js +69 -0
  256. package/bin/lib/mcp-agents.js +1 -6
  257. package/bin/lib/mcp-build.js +1 -1
  258. package/bin/lib/mcp-install.js +2 -1
  259. package/bin/lib/one-shot.js +88 -0
  260. package/bin/lib/path-expand.js +9 -0
  261. package/bin/lib/remote.js +65 -0
  262. package/bin/lib/repl.js +167 -0
  263. package/bin/lib/{utils.js → shell.js} +10 -26
  264. package/bin/lib/skill-check.js +1 -1
  265. package/bin/lib/sse-stream.js +167 -0
  266. package/package.json +2 -2
  267. package/scripts/setup.js +182 -120
  268. package/skills/mindos/SKILL.md +92 -92
  269. package/skills/mindos-zh/SKILL.md +100 -104
  270. package/_standalone/.next/server/chunks/1955.js +0 -11
  271. package/_standalone/.next/server/chunks/3680.js +0 -1
  272. package/_standalone/.next/server/chunks/4497.js +0 -219
  273. package/_standalone/.next/server/chunks/5560.js +0 -2
  274. package/_standalone/.next/static/chunks/1053-0adaccc98a752a58.js +0 -29
  275. package/_standalone/.next/static/chunks/3637.f9a42cca59fd5bb5.js +0 -1
  276. package/_standalone/.next/static/chunks/4563-c2afaeacb241d1d0.js +0 -6
  277. package/_standalone/.next/static/chunks/6090-c98268ca726a68d3.js +0 -1
  278. package/_standalone/.next/static/chunks/9371-575600301da5d6bb.js +0 -1
  279. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-3e08abb495ecd5fd.js +0 -1
  280. package/_standalone/.next/static/chunks/app/agents/page-e7e0f87ad3d765ac.js +0 -5
  281. package/_standalone/.next/static/chunks/app/help/page-3d0e1ceaa4abc243.js +0 -1
  282. package/_standalone/.next/static/chunks/app/setup/page-99ed3d1bb6b8f4ef.js +0 -1
  283. package/_standalone/.next/static/chunks/app/view/[...path]/page-44fa78cbea613a78.js +0 -12
  284. package/_standalone/.next/static/css/d300701f384db50d.css +0 -1
  285. package/_standalone/components/renderers/agent-inspector/manifest.ts +0 -16
  286. /package/_standalone/.next/static/{rZLs1krFuduixvcVNe6q3 → Ij3PFh-a0zi5K_ANoSAW0}/_buildManifest.js +0 -0
  287. /package/_standalone/.next/static/{rZLs1krFuduixvcVNe6q3 → Ij3PFh-a0zi5K_ANoSAW0}/_ssgManifest.js +0 -0
@@ -77,11 +77,12 @@ function countContentFiles(node: FileNode): number {
77
77
  return (node.children ?? []).reduce((sum, c) => sum + countContentFiles(c), 0);
78
78
  }
79
79
 
80
- /** Filter out system files and dot-entries that shouldn't appear by default. */
80
+ /** Filter out hidden entries (dot-files at root, system files) when show-hidden is off. */
81
81
  function filterHiddenNodes(nodes: FileNode[], isRoot: boolean): FileNode[] {
82
82
  return nodes.filter(node => {
83
83
  if (isRoot && node.name.startsWith('.')) return false;
84
84
  if (node.type === 'file' && SYSTEM_FILES.has(node.name)) return false;
85
+ if (node.type === 'directory' && node.name.startsWith('.')) return false;
85
86
  return true;
86
87
  });
87
88
  }
@@ -426,7 +427,7 @@ function DirectoryNode({ node, depth, currentPath, onNavigate, maxOpenDepth, onI
426
427
  onClick={toggle}
427
428
  className="shrink-0 p-1 rounded hover:bg-muted text-muted-foreground transition-colors"
428
429
  style={{ marginLeft: `${depth * 12 + 4}px` }}
429
- aria-label={open ? 'Collapse' : 'Expand'}
430
+ aria-label={open ? `Collapse ${node.name}` : `Expand ${node.name}`}
430
431
  >
431
432
  <span className="block transition-transform duration-150" style={{ transform: open ? 'rotate(0deg)' : 'rotate(-90deg)' }}>
432
433
  <ChevronDown size={13} />
@@ -51,11 +51,18 @@ function CopyButton({ code }: { code: string }) {
51
51
  );
52
52
  }
53
53
 
54
- // Heading components with suppressHydrationWarning to prevent
55
- // rehype-slug + emoji hydration mismatches between server and client
54
+ // react-markdown passes an AST `node` prop to custom components;
55
+ // strip it (and any other non-DOM keys) before forwarding to the real element.
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ function stripNonDom(props: Record<string, any>): Record<string, any> {
58
+ const { node, inline, ordered, depth, isHeader, ...domProps } = props;
59
+ return domProps;
60
+ }
61
+
56
62
  function makeHeading(Tag: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6') {
57
- const HeadingComponent = ({ children, ...props }: React.HTMLAttributes<HTMLHeadingElement>) => (
58
- <Tag {...props} suppressHydrationWarning>{children}</Tag>
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ const HeadingComponent = ({ children, ...props }: any) => (
65
+ <Tag {...stripNonDom(props)} suppressHydrationWarning>{children}</Tag>
59
66
  );
60
67
  HeadingComponent.displayName = Tag;
61
68
  return HeadingComponent;
@@ -68,11 +75,12 @@ const components: Components = {
68
75
  h4: makeHeading('h4'),
69
76
  h5: makeHeading('h5'),
70
77
  h6: makeHeading('h6'),
71
- code({ children, ...props }) {
72
- return <code {...props} suppressHydrationWarning>{children}</code>;
78
+ code({ children, node, ...rest }) {
79
+ void node;
80
+ return <code {...stripNonDom(rest)} suppressHydrationWarning>{children}</code>;
73
81
  },
74
- pre({ children, ...props }) {
75
- // Extract code string from children
82
+ pre({ children, node, ...rest }) {
83
+ void node;
76
84
  let codeString = '';
77
85
  if (children && typeof children === 'object' && 'props' in children) {
78
86
  const codeEl = children as React.ReactElement<{ children?: React.ReactNode }>;
@@ -80,31 +88,38 @@ const components: Components = {
80
88
  }
81
89
  return (
82
90
  <div className="relative group">
83
- <pre {...props} suppressHydrationWarning>{children}</pre>
91
+ <pre {...stripNonDom(rest)} suppressHydrationWarning>{children}</pre>
84
92
  <CopyButton code={codeString} />
85
93
  </div>
86
94
  );
87
95
  },
88
- li({ children, ...props }) {
89
- return <li {...props} suppressHydrationWarning>{children}</li>;
96
+ li({ children, node, ...rest }) {
97
+ void node;
98
+ return <li {...stripNonDom(rest)} suppressHydrationWarning>{children}</li>;
99
+ },
100
+ p({ children, node, ...rest }) {
101
+ void node;
102
+ return <p {...stripNonDom(rest)} suppressHydrationWarning>{children}</p>;
90
103
  },
91
- a({ href, children, ...props }) {
104
+ a({ href, children, node, ...rest }) {
105
+ void node;
92
106
  const isExternal = href?.startsWith('http');
93
107
  return (
94
108
  <a
95
109
  href={href}
96
110
  target={isExternal ? '_blank' : undefined}
97
111
  rel={isExternal ? 'noopener noreferrer' : undefined}
98
- {...props}
112
+ {...stripNonDom(rest)}
99
113
  >
100
114
  {children}
101
115
  </a>
102
116
  );
103
117
  },
104
- img({ src, alt, ...props }) {
118
+ img({ src, alt, node, ...rest }) {
119
+ void node;
105
120
  if (!src) return null;
106
121
  // eslint-disable-next-line @next/next/no-img-element
107
- return <img src={src} alt={alt ?? ''} {...props} />;
122
+ return <img src={src} alt={alt ?? ''} {...stripNonDom(rest)} />;
108
123
  },
109
124
  };
110
125
 
@@ -9,7 +9,9 @@ import { useResizeDrag } from '@/hooks/useResizeDrag';
9
9
  const DEFAULT_WIDTH = 420;
10
10
  const MIN_WIDTH = 400;
11
11
  const MAX_WIDTH_ABS = 4000;
12
- const FOCUS_SNAP_THRESHOLD = 80;
12
+ const ENTER_SNAP_THRESHOLD = 80;
13
+ const EXIT_SNAP_THRESHOLD = 16;
14
+ const MIN_CONTENT_WIDTH = 360;
13
15
 
14
16
  import type { AcpAgentSelection } from '@/hooks/useAskModal';
15
17
 
@@ -37,6 +39,7 @@ export default function RightAskPanel({
37
39
  maximized = false, onMaximize, sidebarOffset = 0,
38
40
  }: RightAskPanelProps) {
39
41
  const snapFiredRef = useRef(false);
42
+ const justExitedMaxRef = useRef(false);
40
43
 
41
44
  const maxAvailable = typeof window !== 'undefined'
42
45
  ? window.innerWidth - sidebarOffset
@@ -45,12 +48,28 @@ export default function RightAskPanel({
45
48
  const handleResize = useCallback((w: number) => {
46
49
  if (snapFiredRef.current) return;
47
50
  const clamped = Math.min(w, maxAvailable);
48
- if (maximized && clamped < maxAvailable - FOCUS_SNAP_THRESHOLD && onMaximize) {
51
+
52
+ // Exit maximized: user drags right even a little (16px) → exit immediately
53
+ if (maximized && clamped < maxAvailable - EXIT_SNAP_THRESHOLD && onMaximize) {
54
+ justExitedMaxRef.current = true;
49
55
  onMaximize();
50
- onWidthChange(clamped);
56
+ const maxPanelForContent = typeof window !== 'undefined'
57
+ ? window.innerWidth - sidebarOffset - MIN_CONTENT_WIDTH
58
+ : clamped;
59
+ onWidthChange(Math.min(clamped, maxPanelForContent));
51
60
  return;
52
61
  }
53
- if (!maximized && clamped >= maxAvailable - FOCUS_SNAP_THRESHOLD && onMaximize) {
62
+
63
+ // Snap to fullscreen: panel near max edge OR content squeezed below minimum.
64
+ // Suppress content-based snap while justExitedMaxRef is true (user recently
65
+ // exited fullscreen and panel is still wide); only re-enable once the panel
66
+ // has been shrunk enough that content is comfortable (reset in handleMouseDown).
67
+ const contentRemaining = typeof window !== 'undefined'
68
+ ? window.innerWidth - sidebarOffset - clamped
69
+ : Infinity;
70
+ const shouldSnap = clamped >= maxAvailable - ENTER_SNAP_THRESHOLD
71
+ || (!justExitedMaxRef.current && contentRemaining < MIN_CONTENT_WIDTH);
72
+ if (!maximized && shouldSnap && onMaximize) {
54
73
  snapFiredRef.current = true;
55
74
  onMaximize();
56
75
  return;
@@ -58,7 +77,7 @@ export default function RightAskPanel({
58
77
  if (!maximized) {
59
78
  onWidthChange(clamped);
60
79
  }
61
- }, [maxAvailable, onMaximize, maximized, onWidthChange]);
80
+ }, [maxAvailable, sidebarOffset, onMaximize, maximized, onWidthChange]);
62
81
 
63
82
  const handleResizeEnd = useCallback((w: number) => {
64
83
  if (snapFiredRef.current) return;
@@ -77,8 +96,19 @@ export default function RightAskPanel({
77
96
 
78
97
  const handleMouseDown = useCallback((e: React.MouseEvent) => {
79
98
  snapFiredRef.current = false;
99
+ // Only re-enable content-based snap once the panel has been shrunk enough
100
+ // that content is comfortably above minimum. This prevents the bounce:
101
+ // exit fullscreen → new drag → immediately re-snap because panel still wide.
102
+ if (justExitedMaxRef.current) {
103
+ const currentContent = typeof window !== 'undefined'
104
+ ? window.innerWidth - sidebarOffset - width
105
+ : Infinity;
106
+ if (currentContent >= MIN_CONTENT_WIDTH) {
107
+ justExitedMaxRef.current = false;
108
+ }
109
+ }
80
110
  rawMouseDown(e);
81
- }, [rawMouseDown]);
111
+ }, [rawMouseDown, sidebarOffset, width]);
82
112
 
83
113
  const effectiveWidth = maximized
84
114
  ? `calc(100vw - ${sidebarOffset}px)`
@@ -102,13 +102,13 @@ export default function Sidebar({ fileTree, collapsed = false, onCollapse, onExp
102
102
  </button>
103
103
  {/* Desktop action buttons — trimmed to 4 */}
104
104
  <div className="hidden md:flex items-center gap-1">
105
- <button onClick={() => setSearchOpen(true)} className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={t.sidebar.searchTitle} aria-label={t.sidebar.searchTitle}>
105
+ <button onClick={() => setSearchOpen(true)} className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={t.sidebar.searchTitle} aria-hidden="true" tabIndex={-1}>
106
106
  <Search size={15} />
107
107
  </button>
108
- <button onClick={() => setSettingsOpen(true)} className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={t.sidebar.settingsTitle} aria-label={t.sidebar.settingsTitle}>
108
+ <button onClick={() => setSettingsOpen(true)} className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={t.sidebar.settingsTitle} aria-hidden="true" tabIndex={-1}>
109
109
  <Settings size={15} />
110
110
  </button>
111
- <button onClick={onCollapse} className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={t.sidebar.collapseTitle} aria-label={t.sidebar.collapseTitle}>
111
+ <button onClick={onCollapse} className="p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={t.sidebar.collapseTitle} aria-hidden="true" tabIndex={-1}>
112
112
  <PanelLeftClose size={15} />
113
113
  </button>
114
114
  </div>
@@ -339,6 +339,9 @@ function ByAgentView({
339
339
  variant="primary"
340
340
  />
341
341
  )}
342
+ {!agent.installed && (
343
+ <span className="text-2xs text-muted-foreground/60">or CLI Skill</span>
344
+ )}
342
345
  </div>
343
346
  </div>
344
347
 
@@ -1,14 +1,16 @@
1
1
  'use client';
2
2
 
3
3
  import { useState } from 'react';
4
- import { CheckCircle2, AlertCircle, Loader2 } from 'lucide-react';
4
+ import { CheckCircle2, AlertCircle, Loader2, Copy } from 'lucide-react';
5
5
  import CustomSelect from '@/components/CustomSelect';
6
6
  import { apiFetch } from '@/lib/api';
7
+ import { copyToClipboard } from '@/lib/clipboard';
8
+ import { toast } from '@/lib/toast';
7
9
  import type { AgentInfo, McpAgentInstallProps } from './types';
8
10
 
9
11
  /* ── Agent Install ─────────────────────────────────────────────── */
10
12
 
11
- export default function AgentInstall({ agents, t, onRefresh }: McpAgentInstallProps) {
13
+ export default function AgentInstall({ agents, t, onRefresh, mode = 'mcp', activeSkillName = 'mindos' }: McpAgentInstallProps) {
12
14
  const m = t.settings?.mcp;
13
15
  const [selected, setSelected] = useState<Set<string>>(new Set());
14
16
  const [transport, setTransport] = useState<'auto' | 'stdio' | 'http'>('auto');
@@ -31,7 +33,8 @@ export default function AgentInstall({ agents, t, onRefresh }: McpAgentInstallPr
31
33
  });
32
34
  };
33
35
 
34
- const handleInstall = async () => {
36
+ /* ── MCP mode: install MCP config via API ── */
37
+ const handleMcpInstall = async () => {
35
38
  if (selected.size === 0) return;
36
39
  setInstalling(true);
37
40
  setMessage(null);
@@ -50,7 +53,6 @@ export default function AgentInstall({ agents, t, onRefresh }: McpAgentInstallPr
50
53
  }),
51
54
  transport,
52
55
  ...(transport === 'http' ? { url: httpUrl, token: httpToken } : {}),
53
- // For auto mode, pass http settings for agents that need it
54
56
  ...(transport === 'auto' ? { url: httpUrl, token: httpToken } : {}),
55
57
  };
56
58
  const res = await apiFetch<{ results: Array<{ agent: string; status: string; message?: string }> }>('/api/mcp/install', {
@@ -81,8 +83,18 @@ export default function AgentInstall({ agents, t, onRefresh }: McpAgentInstallPr
81
83
  return agent?.preferredTransport === 'http';
82
84
  }));
83
85
 
86
+ /* ═══ CLI mode: show skill install commands ═══ */
87
+ if (mode === 'cli') {
88
+ return <CliSkillInstall agents={agents} m={m} activeSkillName={activeSkillName} />;
89
+ }
90
+
91
+ /* ═══ MCP mode: full MCP config install ═══ */
84
92
  return (
85
93
  <div className="space-y-3 pt-2">
94
+ <p className="text-xs text-muted-foreground">
95
+ {m?.mcpInstallDesc ?? 'Install MCP config + Skill to detected agents on this machine.'}
96
+ </p>
97
+
86
98
  {/* Agent list */}
87
99
  <div className="space-y-1">
88
100
  {agents.map(agent => (
@@ -109,7 +121,6 @@ export default function AgentInstall({ agents, t, onRefresh }: McpAgentInstallPr
109
121
  {agent.present ? (m?.detected ?? 'Detected') : (m?.notFound ?? 'Not found')}
110
122
  </span>
111
123
  )}
112
- {/* Scope selector */}
113
124
  {selected.has(agent.key) && agent.hasProjectScope && agent.hasGlobalScope && (
114
125
  <CustomSelect
115
126
  value={scopes[agent.key] || 'project'}
@@ -126,12 +137,10 @@ export default function AgentInstall({ agents, t, onRefresh }: McpAgentInstallPr
126
137
  ))}
127
138
  </div>
128
139
 
129
- {/* Select detected / Clear buttons */}
140
+ {/* Quick select */}
130
141
  <div className="flex gap-2 text-xs pt-1">
131
142
  <button type="button"
132
- onClick={() => setSelected(new Set(
133
- agents.filter(a => !a.installed && a.present).map(a => a.key)
134
- ))}
143
+ onClick={() => setSelected(new Set(agents.filter(a => !a.installed && a.present).map(a => a.key)))}
135
144
  className="px-2.5 py-1 rounded-md border border-[var(--amber)] text-[var(--amber)] transition-colors hover:bg-muted/50">
136
145
  {m?.selectDetected ?? 'Select Detected'}
137
146
  </button>
@@ -163,32 +172,20 @@ export default function AgentInstall({ agents, t, onRefresh }: McpAgentInstallPr
163
172
  <div className="space-y-2 pl-5 text-xs">
164
173
  <div className="space-y-1">
165
174
  <label className="text-muted-foreground">{m?.httpUrl ?? 'MCP URL'}</label>
166
- <input
167
- type="text"
168
- value={httpUrl}
169
- onChange={e => setHttpUrl(e.target.value)}
170
- className="w-full px-2.5 py-1.5 text-xs rounded-md border border-border bg-background font-mono text-foreground outline-none focus-visible:ring-1 focus-visible:ring-ring"
171
- />
175
+ <input type="text" value={httpUrl} onChange={e => setHttpUrl(e.target.value)}
176
+ className="w-full px-2.5 py-1.5 text-xs rounded-md border border-border bg-background font-mono text-foreground outline-none focus-visible:ring-1 focus-visible:ring-ring" />
172
177
  </div>
173
178
  <div className="space-y-1">
174
179
  <label className="text-muted-foreground">{m?.httpToken ?? 'Auth Token'}</label>
175
- <input
176
- type="password"
177
- value={httpToken}
178
- onChange={e => setHttpToken(e.target.value)}
179
- placeholder="Bearer token"
180
- className="w-full px-2.5 py-1.5 text-xs rounded-md border border-border bg-background font-mono text-foreground outline-none focus-visible:ring-1 focus-visible:ring-ring"
181
- />
180
+ <input type="password" value={httpToken} onChange={e => setHttpToken(e.target.value)} placeholder="Bearer token"
181
+ className="w-full px-2.5 py-1.5 text-xs rounded-md border border-border bg-background font-mono text-foreground outline-none focus-visible:ring-1 focus-visible:ring-ring" />
182
182
  </div>
183
183
  </div>
184
184
  )}
185
185
 
186
186
  {/* Install button */}
187
- <button
188
- onClick={handleInstall}
189
- disabled={selected.size === 0 || installing}
190
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-lg transition-colors disabled:opacity-40 disabled:cursor-not-allowed bg-[var(--amber)] text-[var(--amber-foreground)]"
191
- >
187
+ <button onClick={handleMcpInstall} disabled={selected.size === 0 || installing}
188
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-lg transition-colors disabled:opacity-40 disabled:cursor-not-allowed bg-[var(--amber)] text-[var(--amber-foreground)]">
192
189
  {installing && <Loader2 size={12} className="animate-spin" />}
193
190
  {installing ? (m?.installing ?? 'Installing...') : (m?.installSelected ?? 'Install Selected')}
194
191
  </button>
@@ -206,3 +203,73 @@ export default function AgentInstall({ agents, t, onRefresh }: McpAgentInstallPr
206
203
  </div>
207
204
  );
208
205
  }
206
+
207
+ /* ── CLI Skill Install — generates per-agent CLI commands ── */
208
+
209
+ function CliSkillInstall({ agents, m, activeSkillName }: {
210
+ agents: AgentInfo[];
211
+ m: Record<string, any> | undefined;
212
+ activeSkillName: string;
213
+ }) {
214
+ const [selectedAgent, setSelectedAgent] = useState(agents[0]?.key ?? 'claude-code');
215
+ const agent = agents.find(a => a.key === selectedAgent);
216
+ const cmd = `npx skills add GeminiLight/MindOS --skill ${activeSkillName} -a ${selectedAgent} -g -y`;
217
+
218
+ const handleCopy = async () => {
219
+ const ok = await copyToClipboard(cmd);
220
+ if (ok) toast.copy();
221
+ };
222
+
223
+ const connected = agents.filter(a => a.present && a.installed);
224
+ const detected = agents.filter(a => a.present && !a.installed);
225
+ const notFound = agents.filter(a => !a.present);
226
+
227
+ return (
228
+ <div className="space-y-3 pt-2">
229
+ <p className="text-xs text-muted-foreground">
230
+ {m?.cliInstallDesc ?? 'Install the MindOS Skill to your agent so it can operate your knowledge base.'}
231
+ </p>
232
+
233
+ {/* Agent selector */}
234
+ <CustomSelect
235
+ value={selectedAgent}
236
+ onChange={setSelectedAgent}
237
+ size="sm"
238
+ options={[
239
+ ...(connected.length > 0 ? [{ label: m?.connectedGroup ?? 'Connected', options: connected.map(a => ({ value: a.key, label: a.name })) }] : []),
240
+ ...(detected.length > 0 ? [{ label: m?.detectedGroup ?? 'Detected', options: detected.map(a => ({ value: a.key, label: a.name })) }] : []),
241
+ ...(notFound.length > 0 ? [{ label: m?.notFoundGroup ?? 'Not Installed', options: notFound.map(a => ({ value: a.key, label: a.name })) }] : []),
242
+ ]}
243
+ />
244
+
245
+ {/* Status */}
246
+ {agent && (
247
+ <div className="flex items-center gap-2 text-2xs">
248
+ {agent.present && agent.installed ? (
249
+ <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full font-medium bg-success/10 text-success">
250
+ <CheckCircle2 size={10} /> {m?.tagConnected ?? 'Connected'}
251
+ </span>
252
+ ) : agent.present ? (
253
+ <span className="text-muted-foreground">{m?.detected ?? 'Detected'}</span>
254
+ ) : (
255
+ <span className="text-muted-foreground">{m?.notFound ?? 'Not found'}</span>
256
+ )}
257
+ {agent.installedSkillCount != null && agent.installedSkillCount > 0 && (
258
+ <span className="text-muted-foreground">{agent.installedSkillCount} {m?.skillsInstalled ?? 'skills installed'}</span>
259
+ )}
260
+ </div>
261
+ )}
262
+
263
+ {/* Command */}
264
+ <div className="flex items-center gap-1.5">
265
+ <code className="flex-1 text-[10px] font-mono bg-muted/50 border border-border rounded-lg px-2.5 py-2 text-muted-foreground select-all overflow-x-auto whitespace-nowrap">
266
+ {cmd}
267
+ </code>
268
+ <button onClick={handleCopy}
269
+ className="p-1.5 rounded-md border border-border text-muted-foreground hover:text-foreground hover:bg-muted transition-colors shrink-0">
270
+ <Copy size={11} />
271
+ </button>
272
+ </div>
273
+ </div>
274
+ );
275
+ }
@@ -29,7 +29,7 @@ export default function SkillsSection({ t }: McpSkillsSectionProps) {
29
29
  const [createError, setCreateError] = useState('');
30
30
 
31
31
  const [search, setSearch] = useState('');
32
- const [builtinCollapsed, setBuiltinCollapsed] = useState(false);
32
+ const [builtinCollapsed, setBuiltinCollapsed] = useState(true);
33
33
  const [editing, setEditing] = useState<string | null>(null);
34
34
  const [editContent, setEditContent] = useState('');
35
35
  const [editError, setEditError] = useState('');