@geminilight/mindos 0.6.40 → 0.6.42
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.
- package/_standalone/.mindos-build-version +1 -1
- package/_standalone/.next/BUILD_ID +1 -1
- package/_standalone/.next/app-path-routes-manifest.json +17 -16
- package/_standalone/.next/build-manifest.json +3 -3
- package/_standalone/.next/cache/.previewinfo +1 -1
- package/_standalone/.next/cache/.rscinfo +1 -1
- package/_standalone/.next/cache/config.json +3 -3
- package/_standalone/.next/prerender-manifest.json +3 -3
- package/_standalone/.next/react-loadable-manifest.json +5 -1
- package/_standalone/.next/routes-manifest.json +6 -0
- package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +1 -1
- package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/page.js +2 -2
- package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/uninstall/route.js +1 -0
- package/_standalone/.next/server/app/api/mcp/uninstall/route.js.nft.json +1 -0
- package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -0
- package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/skills/route.js +4 -4
- package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changes/page.js +1 -1
- package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/page.js +1 -1
- package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/explore/page.js +1 -1
- package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/help/page.js +2 -2
- package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/login/page.js +1 -1
- package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/page.js +2 -2
- package/_standalone/.next/server/app/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/setup/page.js +2 -2
- package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/trash/page.js +3 -3
- package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
- package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +17 -16
- package/_standalone/.next/server/chunks/1550.js +1 -1
- package/_standalone/.next/server/chunks/2190.js +11 -0
- package/_standalone/.next/server/chunks/{6365.js → 3262.js} +2 -2
- package/_standalone/.next/server/chunks/5648.js +2 -0
- package/_standalone/.next/server/chunks/6539.js +1 -1
- package/_standalone/.next/server/chunks/8388.js +1 -1
- package/_standalone/.next/server/chunks/953.js +1 -1
- package/_standalone/.next/server/chunks/9539.js +219 -0
- package/_standalone/.next/server/middleware-build-manifest.js +1 -1
- package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/_standalone/.next/server/next-font-manifest.js +1 -1
- package/_standalone/.next/server/next-font-manifest.json +1 -1
- package/_standalone/.next/server/pages/500.html +2 -2
- package/_standalone/.next/server/server-reference-manifest.js +1 -1
- package/_standalone/.next/server/server-reference-manifest.json +1 -1
- package/_standalone/.next/static/GB-YReQ58tsvCuwlzrkMZ/_buildManifest.js +1 -0
- package/_standalone/.next/static/chunks/1053-67f0ce444d1227e2.js +29 -0
- package/_standalone/.next/static/chunks/{8663-de911d2d395622be.js → 1880-c2a9e76201841c86.js} +1 -1
- package/_standalone/.next/static/chunks/3637.0541ac2d0ea7de1f.js +1 -0
- package/_standalone/.next/static/chunks/4563-b2a2ce80aff845af.js +6 -0
- package/_standalone/.next/static/chunks/6981-3d7dcac2d12a5670.js +1 -0
- package/_standalone/.next/static/chunks/7144-5febf62f1a79fe64.js +1 -0
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/_global-error/page-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-773071a99c4daac2.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/page-eac6c5f6650dbf62.js +5 -0
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/config/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/install/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/session/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/auth/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/backlinks/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/changes/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/export/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/import/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/files/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/git/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/graph/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/health/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/init/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/monitoring/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/recent-files/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/restart/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/search/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/skills/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/sync/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/tree-version/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/uninstall/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-check/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-status/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/workflows/route-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/echo/page-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/help/page-2325d25b6846ca07.js +1 -0
- package/_standalone/.next/static/chunks/app/{layout-9378c1c8d3e5761b.js → layout-7cb442df92212140.js} +55 -55
- package/_standalone/.next/static/chunks/app/{page-9bae420fbbdc5fff.js → page-aaee2d9bd3d3eabb.js} +1 -1
- package/_standalone/.next/static/chunks/app/setup/page-6132ea7632e08a9b.js +1 -0
- package/_standalone/.next/static/chunks/app/trash/{page-b61ef2d5cd4f8d73.js → page-7b5cbf541c315db2.js} +1 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-b72e4f88c8c48181.js +12 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-84943536516b00b2.js +1 -0
- package/_standalone/.next/static/chunks/{webpack-c28c55d0a6021a6b.js → webpack-7b276daaa930d480.js} +1 -1
- package/_standalone/.next/static/css/bc9179074eaf65ae.css +1 -0
- package/_standalone/.next/trace +63 -63
- package/_standalone/.next/types/routes.d.ts +2 -1
- package/_standalone/.next/types/validator.ts +9 -0
- package/_standalone/__tests__/api/mcp-install.test.ts +23 -0
- package/_standalone/__tests__/cli/agent-routing.test.ts +232 -0
- package/_standalone/__tests__/cli/file-subcommands.test.ts +379 -0
- package/_standalone/__tests__/core/tools.test.ts +3 -6
- package/_standalone/components/FileTree.tsx +3 -2
- package/_standalone/components/MarkdownView.tsx +30 -15
- package/_standalone/components/RightAskPanel.tsx +36 -6
- package/_standalone/components/Sidebar.tsx +3 -3
- package/_standalone/components/agents/AgentsMcpSection.tsx +27 -5
- package/_standalone/components/settings/McpAgentInstall.tsx +94 -27
- package/_standalone/components/settings/McpSkillsSection.tsx +1 -1
- package/_standalone/components/settings/McpTab.tsx +484 -340
- package/_standalone/components/settings/SettingsContent.tsx +12 -6
- package/_standalone/components/settings/types.ts +3 -0
- package/_standalone/components/setup/StepAgents.tsx +113 -47
- package/_standalone/components/setup/StepReview.tsx +14 -27
- package/_standalone/components/setup/types.ts +7 -0
- package/_standalone/data/skills/mindos/SKILL.md +92 -92
- package/_standalone/data/skills/mindos/references/write-supplement.md +119 -0
- package/_standalone/data/skills/mindos-zh/SKILL.md +100 -104
- package/_standalone/data/skills/mindos-zh/references/write-supplement.md +119 -0
- package/_standalone/lib/i18n/modules/features.ts +4 -4
- package/_standalone/lib/i18n/modules/knowledge.ts +4 -0
- package/_standalone/lib/i18n/modules/onboarding.ts +40 -30
- package/_standalone/lib/i18n/modules/panels.ts +6 -2
- package/_standalone/lib/i18n/modules/settings.ts +78 -6
- package/_standalone/lib/mcp-snippets.ts +5 -1
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/api/ask/route.ts +3 -2
- package/app/app/api/mcp/install/route.ts +15 -3
- package/app/app/api/mcp/status/route.ts +14 -6
- package/app/app/api/mcp/uninstall/route.ts +130 -0
- package/app/app/api/skills/route.ts +14 -1
- package/app/app/view/[...path]/ViewPageClient.tsx +12 -27
- package/app/components/FileTree.tsx +3 -2
- package/app/components/MarkdownView.tsx +30 -15
- package/app/components/RightAskPanel.tsx +36 -6
- package/app/components/Sidebar.tsx +3 -3
- package/app/components/agents/AgentsMcpSection.tsx +27 -5
- package/app/components/help/HelpContent.tsx +1 -0
- package/app/components/settings/McpAgentInstall.tsx +94 -27
- package/app/components/settings/McpSkillsSection.tsx +1 -1
- package/app/components/settings/McpTab.tsx +484 -340
- package/app/components/settings/SettingsContent.tsx +12 -6
- package/app/components/settings/types.ts +3 -0
- package/app/components/setup/StepAgents.tsx +113 -47
- package/app/components/setup/StepReview.tsx +14 -27
- package/app/components/setup/index.tsx +16 -14
- package/app/components/setup/types.ts +7 -0
- package/app/data/skills/mindos/SKILL.md +92 -92
- package/app/data/skills/mindos/references/write-supplement.md +119 -0
- package/app/data/skills/mindos-zh/SKILL.md +100 -104
- package/app/data/skills/mindos-zh/references/write-supplement.md +119 -0
- package/app/lib/fs.ts +0 -6
- package/app/lib/i18n/modules/features.ts +4 -4
- package/app/lib/i18n/modules/knowledge.ts +4 -0
- package/app/lib/i18n/modules/onboarding.ts +40 -30
- package/app/lib/i18n/modules/panels.ts +6 -2
- package/app/lib/i18n/modules/settings.ts +78 -6
- package/app/lib/mcp-agents.ts +1 -2
- package/app/lib/mcp-snippets.ts +5 -1
- package/app/lib/renderers/index.ts +2 -1
- package/app/lib/settings.ts +32 -0
- package/bin/cli.js +168 -1404
- package/bin/commands/agent.js +156 -20
- package/bin/commands/api.js +14 -11
- package/bin/commands/ask.js +79 -68
- package/bin/commands/build.js +26 -0
- package/bin/commands/config.js +170 -0
- package/bin/commands/dev.js +58 -0
- package/bin/commands/doctor.js +205 -0
- package/bin/commands/file.js +551 -36
- package/bin/commands/gateway.js +42 -0
- package/bin/commands/init-skills.js +56 -0
- package/bin/commands/logs.js +32 -0
- package/bin/commands/mcp-cmd.js +57 -0
- package/bin/commands/onboard.js +25 -0
- package/bin/commands/open.js +41 -0
- package/bin/commands/restart.js +48 -0
- package/bin/commands/search.js +16 -14
- package/bin/commands/space.js +96 -25
- package/bin/commands/start.js +272 -0
- package/bin/commands/status.js +2 -2
- package/bin/commands/stop.js +14 -0
- package/bin/commands/sync-cmd.js +134 -0
- package/bin/commands/token.js +98 -0
- package/bin/commands/uninstall.js +154 -0
- package/bin/commands/update.js +286 -0
- package/bin/lib/build.js +1 -1
- package/bin/lib/colors.js +8 -7
- package/bin/lib/command.js +37 -96
- package/bin/lib/config.js +5 -0
- package/bin/lib/csv.js +19 -0
- package/bin/lib/jsonc.js +12 -0
- package/bin/lib/markdown.js +69 -0
- package/bin/lib/mcp-agents.js +1 -6
- package/bin/lib/mcp-build.js +1 -1
- package/bin/lib/mcp-install.js +2 -1
- package/bin/lib/one-shot.js +88 -0
- package/bin/lib/path-expand.js +9 -0
- package/bin/lib/remote.js +65 -0
- package/bin/lib/repl.js +167 -0
- package/bin/lib/{utils.js → shell.js} +10 -26
- package/bin/lib/skill-check.js +116 -21
- package/bin/lib/sse-stream.js +167 -0
- package/package.json +2 -2
- package/scripts/setup.js +210 -120
- package/skills/mindos/SKILL.md +94 -95
- package/skills/mindos-zh/SKILL.md +103 -106
- package/_standalone/.next/server/chunks/1955.js +0 -11
- package/_standalone/.next/server/chunks/3680.js +0 -1
- package/_standalone/.next/server/chunks/4497.js +0 -219
- package/_standalone/.next/server/chunks/5560.js +0 -2
- package/_standalone/.next/static/chunks/1053-0adaccc98a752a58.js +0 -29
- package/_standalone/.next/static/chunks/3637.f9a42cca59fd5bb5.js +0 -1
- package/_standalone/.next/static/chunks/4563-c2afaeacb241d1d0.js +0 -6
- package/_standalone/.next/static/chunks/6090-c98268ca726a68d3.js +0 -1
- package/_standalone/.next/static/chunks/9371-575600301da5d6bb.js +0 -1
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/_global-error/page-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-3e08abb495ecd5fd.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/page-e7e0f87ad3d765ac.js +0 -5
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/config/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/install/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/session/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/auth/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/backlinks/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/changes/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/export/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/import/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/files/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/git/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/graph/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/health/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/inbox/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/init/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/monitoring/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/recent-files/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/restart/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/search/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/skills/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/sync/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/tree-version/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/uninstall/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-check/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-status/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/api/workflows/route-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/page-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/help/page-3d0e1ceaa4abc243.js +0 -1
- package/_standalone/.next/static/chunks/app/setup/page-99ed3d1bb6b8f4ef.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-44fa78cbea613a78.js +0 -12
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-400c3c09b1540c14.js +0 -1
- package/_standalone/.next/static/css/d300701f384db50d.css +0 -1
- package/_standalone/.next/static/rZLs1krFuduixvcVNe6q3/_buildManifest.js +0 -1
- package/_standalone/components/renderers/agent-inspector/manifest.ts +0 -16
- /package/_standalone/.next/static/{rZLs1krFuduixvcVNe6q3 → GB-YReQ58tsvCuwlzrkMZ}/_ssgManifest.js +0 -0
package/app/app/api/ask/route.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
type ToolDefinition,
|
|
14
14
|
SessionManager,
|
|
15
15
|
SettingsManager,
|
|
16
|
+
bashTool,
|
|
16
17
|
} from '@mariozechner/pi-coding-agent';
|
|
17
18
|
import { NextRequest, NextResponse } from 'next/server';
|
|
18
19
|
import fs from 'fs';
|
|
@@ -316,7 +317,7 @@ function toPiCustomToolDefinitions(tools: AgentTool<any>[]): ToolDefinition<any,
|
|
|
316
317
|
params: args,
|
|
317
318
|
result: outputText.startsWith('Error:') ? 'error' : 'ok',
|
|
318
319
|
message: outputText.slice(0, 200),
|
|
319
|
-
agentName: 'MindOS
|
|
320
|
+
agentName: 'MindOS',
|
|
320
321
|
});
|
|
321
322
|
} catch {
|
|
322
323
|
// logging must never kill the stream
|
|
@@ -669,7 +670,7 @@ export async function POST(req: NextRequest) {
|
|
|
669
670
|
resourceLoader,
|
|
670
671
|
sessionManager: SessionManager.inMemory(),
|
|
671
672
|
settingsManager,
|
|
672
|
-
tools: [],
|
|
673
|
+
tools: askMode === 'agent' ? [bashTool] : [],
|
|
673
674
|
customTools,
|
|
674
675
|
});
|
|
675
676
|
|
|
@@ -2,13 +2,14 @@ export const dynamic = 'force-dynamic';
|
|
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import { MCP_AGENTS, expandHome } from '@/lib/mcp-agents';
|
|
6
|
-
import { readSettings } from '@/lib/settings';
|
|
5
|
+
import { MCP_AGENTS, expandHome, resolveSkillWorkspaceProfile } from '@/lib/mcp-agents';
|
|
6
|
+
import { readSettings, recordSkillInstall } from '@/lib/settings';
|
|
7
7
|
|
|
8
|
-
/** Parse JSONC — strips
|
|
8
|
+
/** Parse JSONC — strips comments before JSON.parse. Returns {} for empty/whitespace-only input. */
|
|
9
9
|
function parseJsonc(text: string): Record<string, unknown> {
|
|
10
10
|
let stripped = text.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*$)/gm, (m, g) => g ? '' : m);
|
|
11
11
|
stripped = stripped.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
12
|
+
if (!stripped.trim()) return {};
|
|
12
13
|
return JSON.parse(stripped);
|
|
13
14
|
}
|
|
14
15
|
|
|
@@ -203,6 +204,17 @@ export async function POST(req: NextRequest) {
|
|
|
203
204
|
|
|
204
205
|
const result: typeof results[number] = { agent: key, status: 'ok', path: configPath, transport: effectiveTransport };
|
|
205
206
|
|
|
207
|
+
// Record skill install path for auto-update on future version bumps
|
|
208
|
+
try {
|
|
209
|
+
const skillProfile = resolveSkillWorkspaceProfile(key);
|
|
210
|
+
const settings = readSettings();
|
|
211
|
+
const activeSkill = settings.disabledSkills?.includes('mindos') ? 'mindos-zh' : 'mindos';
|
|
212
|
+
const skillPath = path.join(skillProfile.workspacePath, activeSkill, 'SKILL.md');
|
|
213
|
+
if (fs.existsSync(skillPath)) {
|
|
214
|
+
recordSkillInstall(key, activeSkill, skillPath);
|
|
215
|
+
}
|
|
216
|
+
} catch { /* best-effort, don't fail the install */ }
|
|
217
|
+
|
|
206
218
|
// Verify http connections
|
|
207
219
|
if (effectiveTransport === 'http') {
|
|
208
220
|
const mcpUrl = (entry as Record<string, unknown>).url as string;
|
|
@@ -2,18 +2,29 @@ export const dynamic = 'force-dynamic';
|
|
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
|
3
3
|
import { readSettings } from '@/lib/settings';
|
|
4
4
|
import { maskToken } from '@/lib/format';
|
|
5
|
+
import { networkInterfaces } from 'os';
|
|
5
6
|
|
|
6
7
|
/** Parse hostname from Host header, handling IPv6 brackets */
|
|
7
8
|
function parseHostname(host: string): string {
|
|
8
|
-
// IPv6: [::1]:3003 → [::1]
|
|
9
9
|
if (host.includes(']')) {
|
|
10
10
|
return host.slice(0, host.lastIndexOf(']') + 1);
|
|
11
11
|
}
|
|
12
|
-
// IPv4/hostname: 192.168.1.1:3003 → 192.168.1.1
|
|
13
12
|
const colonIdx = host.lastIndexOf(':');
|
|
14
13
|
return colonIdx > 0 ? host.slice(0, colonIdx) : host;
|
|
15
14
|
}
|
|
16
15
|
|
|
16
|
+
/** Get first non-internal IPv4 address */
|
|
17
|
+
function getLocalIP(): string | null {
|
|
18
|
+
try {
|
|
19
|
+
for (const ifaces of Object.values(networkInterfaces())) {
|
|
20
|
+
for (const iface of ifaces ?? []) {
|
|
21
|
+
if (iface.family === 'IPv4' && !iface.internal) return iface.address;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
} catch { /* ignore */ }
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
17
28
|
export async function GET(req: NextRequest) {
|
|
18
29
|
try {
|
|
19
30
|
const settings = readSettings();
|
|
@@ -52,12 +63,9 @@ export async function GET(req: NextRequest) {
|
|
|
52
63
|
port,
|
|
53
64
|
toolCount: running ? 24 : 0,
|
|
54
65
|
authConfigured,
|
|
55
|
-
// Masked for display; full token only used server-side in snippet generation
|
|
56
66
|
maskedToken: authConfigured ? maskToken(token) : undefined,
|
|
57
|
-
// Full token for config snippet copy — this API is protected by proxy.ts middleware
|
|
58
|
-
// (same-origin or bearer token required). Consistent with /api/settings which also
|
|
59
|
-
// exposes the token to authenticated users.
|
|
60
67
|
authToken: authConfigured ? token : undefined,
|
|
68
|
+
localIP: getLocalIP(),
|
|
61
69
|
});
|
|
62
70
|
} catch (err) {
|
|
63
71
|
return NextResponse.json({ error: String(err) }, { status: 500 });
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
export const dynamic = 'force-dynamic';
|
|
2
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { MCP_AGENTS, expandHome } from '@/lib/mcp-agents';
|
|
6
|
+
|
|
7
|
+
/** Parse JSONC — strips comments before JSON.parse. Returns {} for empty/whitespace-only input. */
|
|
8
|
+
function parseJsonc(text: string): Record<string, unknown> {
|
|
9
|
+
let stripped = text.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*$)/gm, (m, g) => g ? '' : m);
|
|
10
|
+
stripped = stripped.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
11
|
+
if (!stripped.trim()) return {};
|
|
12
|
+
return JSON.parse(stripped);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Navigate a dot-path (e.g. "mcp.servers") and return the leaf container, or null. */
|
|
16
|
+
function getNestedPath(obj: Record<string, unknown>, dotPath: string): Record<string, unknown> | null {
|
|
17
|
+
const parts = dotPath.split('.').filter(Boolean);
|
|
18
|
+
let current: unknown = obj;
|
|
19
|
+
for (const part of parts) {
|
|
20
|
+
if (!current || typeof current !== 'object') return null;
|
|
21
|
+
current = (current as Record<string, unknown>)[part];
|
|
22
|
+
}
|
|
23
|
+
return (current && typeof current === 'object') ? current as Record<string, unknown> : null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Remove a [section.server] block from a TOML file */
|
|
27
|
+
function removeTomlEntry(existing: string, sectionKey: string, serverName: string): string {
|
|
28
|
+
const sectionHeader = `[${sectionKey}.${serverName}]`;
|
|
29
|
+
const envHeader = `[${sectionKey}.${serverName}.env]`;
|
|
30
|
+
const headersHeader = `[${sectionKey}.${serverName}.headers]`;
|
|
31
|
+
|
|
32
|
+
const lines = existing.split('\n');
|
|
33
|
+
const result: string[] = [];
|
|
34
|
+
let skipping = false;
|
|
35
|
+
|
|
36
|
+
for (const line of lines) {
|
|
37
|
+
const trimmed = line.trim();
|
|
38
|
+
if (trimmed === sectionHeader || trimmed === envHeader || trimmed === headersHeader) {
|
|
39
|
+
skipping = true;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (skipping && trimmed.startsWith('[')) {
|
|
43
|
+
skipping = false;
|
|
44
|
+
}
|
|
45
|
+
if (!skipping) {
|
|
46
|
+
result.push(line);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Clean up consecutive blank lines
|
|
51
|
+
const cleaned: string[] = [];
|
|
52
|
+
for (const line of result) {
|
|
53
|
+
if (line.trim() === '' && cleaned.length > 0 && cleaned[cleaned.length - 1].trim() === '') continue;
|
|
54
|
+
cleaned.push(line);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return cleaned.join('\n');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface UninstallRequest {
|
|
61
|
+
agents: Array<{
|
|
62
|
+
key: string;
|
|
63
|
+
scope: 'project' | 'global';
|
|
64
|
+
}>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export async function POST(req: NextRequest) {
|
|
68
|
+
try {
|
|
69
|
+
const body = (await req.json()) as UninstallRequest;
|
|
70
|
+
const { agents } = body;
|
|
71
|
+
const results: Array<{
|
|
72
|
+
agent: string;
|
|
73
|
+
status: string;
|
|
74
|
+
path?: string;
|
|
75
|
+
message?: string;
|
|
76
|
+
}> = [];
|
|
77
|
+
|
|
78
|
+
for (const item of agents) {
|
|
79
|
+
const { key, scope } = item;
|
|
80
|
+
const agent = MCP_AGENTS[key];
|
|
81
|
+
if (!agent) {
|
|
82
|
+
results.push({ agent: key, status: 'error', message: `Unknown agent: ${key}` });
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const isGlobal = scope === 'global';
|
|
87
|
+
const configPath = isGlobal ? agent.global : agent.project;
|
|
88
|
+
if (!configPath) {
|
|
89
|
+
results.push({ agent: key, status: 'error', message: `${agent.name} does not support ${scope} scope` });
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const absPath = expandHome(configPath);
|
|
94
|
+
|
|
95
|
+
if (!fs.existsSync(absPath)) {
|
|
96
|
+
results.push({ agent: key, status: 'ok', message: 'Config file does not exist' });
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
if (agent.format === 'toml') {
|
|
102
|
+
const existing = fs.readFileSync(absPath, 'utf-8');
|
|
103
|
+
const updated = removeTomlEntry(existing, agent.key, 'mindos');
|
|
104
|
+
fs.writeFileSync(absPath, updated, 'utf-8');
|
|
105
|
+
} else {
|
|
106
|
+
const config = parseJsonc(fs.readFileSync(absPath, 'utf-8'));
|
|
107
|
+
|
|
108
|
+
// Handle nested keys (e.g. VS Code: mcp.servers)
|
|
109
|
+
const useNestedKey = isGlobal && agent.globalNestedKey;
|
|
110
|
+
const container = useNestedKey
|
|
111
|
+
? getNestedPath(config, agent.globalNestedKey!)
|
|
112
|
+
: (config[agent.key] as Record<string, unknown> | undefined);
|
|
113
|
+
|
|
114
|
+
if (container && 'mindos' in container) {
|
|
115
|
+
delete container.mindos;
|
|
116
|
+
fs.writeFileSync(absPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
results.push({ agent: key, status: 'ok', path: configPath });
|
|
121
|
+
} catch (err) {
|
|
122
|
+
results.push({ agent: key, status: 'error', message: String(err) });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return NextResponse.json({ results });
|
|
127
|
+
} catch (err) {
|
|
128
|
+
return NextResponse.json({ error: String(err) }, { status: 500 });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -32,7 +32,7 @@ export async function POST(req: NextRequest) {
|
|
|
32
32
|
try {
|
|
33
33
|
const body = await req.json();
|
|
34
34
|
const { action, name, description, content, enabled, sourcePath } = body as {
|
|
35
|
-
action: 'create' | 'update' | 'delete' | 'toggle' | 'read' | 'read-native';
|
|
35
|
+
action: 'create' | 'update' | 'delete' | 'toggle' | 'read' | 'read-native' | 'record-install';
|
|
36
36
|
name?: string;
|
|
37
37
|
description?: string;
|
|
38
38
|
content?: string;
|
|
@@ -130,6 +130,19 @@ export async function POST(req: NextRequest) {
|
|
|
130
130
|
return NextResponse.json({ content: nativeContent, description: nativeDesc });
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
case 'record-install': {
|
|
134
|
+
// Record that a skill was installed to a specific agent (for auto-update tracking)
|
|
135
|
+
const agentKey = (body as { agentKey?: string }).agentKey;
|
|
136
|
+
const skillName = name;
|
|
137
|
+
const installPath = (body as { installPath?: string }).installPath;
|
|
138
|
+
if (!agentKey || !skillName || !installPath) {
|
|
139
|
+
return NextResponse.json({ error: 'agentKey, name, and installPath are required' }, { status: 400 });
|
|
140
|
+
}
|
|
141
|
+
const { recordSkillInstall } = await import('@/lib/settings');
|
|
142
|
+
recordSkillInstall(agentKey, skillName, installPath);
|
|
143
|
+
return NextResponse.json({ ok: true });
|
|
144
|
+
}
|
|
145
|
+
|
|
133
146
|
default:
|
|
134
147
|
return NextResponse.json({ error: `Unknown action: ${action}` }, { status: 400 });
|
|
135
148
|
}
|
|
@@ -58,8 +58,8 @@ export default function ViewPageClient({
|
|
|
58
58
|
);
|
|
59
59
|
|
|
60
60
|
const [useRaw, setUseRaw] = useRendererState<boolean>('_raw', filePath, false);
|
|
61
|
-
//
|
|
62
|
-
const [graphMode, setGraphMode] =
|
|
61
|
+
// Graph mode — per-view, resets when navigating to a different file
|
|
62
|
+
const [graphMode, setGraphMode] = useState(false);
|
|
63
63
|
const router = useRouter();
|
|
64
64
|
const [editing, setEditing] = useState(initialEditing || content === '');
|
|
65
65
|
const [editContent, setEditContent] = useState(content);
|
|
@@ -167,7 +167,7 @@ export default function ViewPageClient({
|
|
|
167
167
|
setGraphMode(prev => !prev);
|
|
168
168
|
}, [setGraphMode]);
|
|
169
169
|
|
|
170
|
-
const effectiveGraphMode =
|
|
170
|
+
const effectiveGraphMode = graphMode;
|
|
171
171
|
|
|
172
172
|
// Resolve renderer: for md files, graph mode overrides normal resolution
|
|
173
173
|
const registryRenderer = resolveRenderer(filePath, extension);
|
|
@@ -383,22 +383,6 @@ export default function ViewPageClient({
|
|
|
383
383
|
<span className="text-xs text-error hidden sm:inline">{saveError}</span>
|
|
384
384
|
)}
|
|
385
385
|
|
|
386
|
-
{/* Graph toggle — only for md files, hidden when graph plugin is disabled */}
|
|
387
|
-
{extension === 'md' && !editing && !isDraft && isRendererEnabled('graph') && (
|
|
388
|
-
<button
|
|
389
|
-
onClick={handleToggleGraph}
|
|
390
|
-
className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors font-display"
|
|
391
|
-
style={{
|
|
392
|
-
background: effectiveGraphMode ? `${'var(--amber)'}22` : 'var(--muted)',
|
|
393
|
-
color: effectiveGraphMode ? 'var(--amber)' : 'var(--muted-foreground)',
|
|
394
|
-
}}
|
|
395
|
-
title={effectiveGraphMode ? 'Switch to document view' : 'Switch to Wiki Graph'}
|
|
396
|
-
>
|
|
397
|
-
{effectiveGraphMode ? <FileText size={13} /> : <Share2 size={13} />}
|
|
398
|
-
<span className="hidden sm:inline">{effectiveGraphMode ? 'Doc' : 'Graph'}</span>
|
|
399
|
-
</button>
|
|
400
|
-
)}
|
|
401
|
-
|
|
402
386
|
{/* Renderer toggle — only shown when a custom renderer exists (excludes graph-mode override) */}
|
|
403
387
|
{registryRenderer && !editing && !isDraft && !graphRenderer && (
|
|
404
388
|
<button
|
|
@@ -463,14 +447,6 @@ export default function ViewPageClient({
|
|
|
463
447
|
>
|
|
464
448
|
<Star size={16} className={pinned ? 'fill-[var(--amber)] text-[var(--amber)]' : ''} />
|
|
465
449
|
</button>
|
|
466
|
-
<button
|
|
467
|
-
type="button"
|
|
468
|
-
onClick={() => setExportOpen(true)}
|
|
469
|
-
className="p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
|
|
470
|
-
title={t.fileTree.export}
|
|
471
|
-
>
|
|
472
|
-
<Download size={16} />
|
|
473
|
-
</button>
|
|
474
450
|
<button
|
|
475
451
|
ref={moreRef}
|
|
476
452
|
type="button"
|
|
@@ -485,6 +461,15 @@ export default function ViewPageClient({
|
|
|
485
461
|
ref={moreMenuRef}
|
|
486
462
|
className="absolute right-0 top-full mt-1 z-50 min-w-[160px] rounded-lg border border-border bg-card shadow-lg py-1"
|
|
487
463
|
>
|
|
464
|
+
{extension === 'md' && !editing && !isDraft && isRendererEnabled('graph') && (
|
|
465
|
+
<button className="w-full flex items-center gap-2 px-3 py-2 text-sm text-foreground hover:bg-muted transition-colors text-left" onClick={() => { setMoreOpen(false); handleToggleGraph(); }}>
|
|
466
|
+
{effectiveGraphMode ? <FileText size={14} className="shrink-0" /> : <Share2 size={14} className="shrink-0" />}
|
|
467
|
+
{effectiveGraphMode ? (t.view?.switchToDoc ?? 'Document view') : (t.view?.switchToGraph ?? 'Wiki Graph')}
|
|
468
|
+
</button>
|
|
469
|
+
)}
|
|
470
|
+
<button className="w-full flex items-center gap-2 px-3 py-2 text-sm text-foreground hover:bg-muted transition-colors text-left" onClick={() => { setMoreOpen(false); setExportOpen(true); }}>
|
|
471
|
+
<Download size={14} className="shrink-0" /> {t.fileTree?.export ?? 'Export'}
|
|
472
|
+
</button>
|
|
488
473
|
<button className="w-full flex items-center gap-2 px-3 py-2 text-sm text-foreground hover:bg-muted transition-colors text-left" onClick={handleCopyPath}>
|
|
489
474
|
<Copy size={14} className="shrink-0" /> {t.view?.copyPath ?? t.fileTree?.copyPath ?? 'Copy Path'}
|
|
490
475
|
</button>
|
|
@@ -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
|
|
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 ?
|
|
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
|
-
//
|
|
55
|
-
//
|
|
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
|
-
|
|
58
|
-
|
|
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, ...
|
|
72
|
-
|
|
78
|
+
code({ children, node, ...rest }) {
|
|
79
|
+
void node;
|
|
80
|
+
return <code {...stripNonDom(rest)} suppressHydrationWarning>{children}</code>;
|
|
73
81
|
},
|
|
74
|
-
pre({ children, ...
|
|
75
|
-
|
|
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 {...
|
|
91
|
+
<pre {...stripNonDom(rest)} suppressHydrationWarning>{children}</pre>
|
|
84
92
|
<CopyButton code={codeString} />
|
|
85
93
|
</div>
|
|
86
94
|
);
|
|
87
95
|
},
|
|
88
|
-
li({ children, ...
|
|
89
|
-
|
|
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, ...
|
|
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
|
-
{...
|
|
112
|
+
{...stripNonDom(rest)}
|
|
99
113
|
>
|
|
100
114
|
{children}
|
|
101
115
|
</a>
|
|
102
116
|
);
|
|
103
117
|
},
|
|
104
|
-
img({ src, alt, ...
|
|
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 ?? ''} {...
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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>
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { useCallback, useMemo, useState } from 'react';
|
|
4
4
|
import Link from 'next/link';
|
|
5
5
|
import { RefreshCw, Search, Server } from 'lucide-react';
|
|
6
|
+
import { apiFetch } from '@/lib/api';
|
|
6
7
|
import type { McpContextValue } from '@/lib/stores/mcp-store';
|
|
7
8
|
import type { AgentBuckets, AgentStatusFilter, AgentTransportFilter } from './agents-content-model';
|
|
8
9
|
import {
|
|
@@ -58,6 +59,8 @@ export default function AgentsMcpSection({
|
|
|
58
59
|
cancel: string;
|
|
59
60
|
noAvailableAgents: string;
|
|
60
61
|
manualRemoveHint: string;
|
|
62
|
+
removeSuccess: string;
|
|
63
|
+
removeFailed: string;
|
|
61
64
|
reconnectAllInServer: string;
|
|
62
65
|
reconnectAllRunning: string;
|
|
63
66
|
reconnectAllDone: (ok: number, failed: number) => string;
|
|
@@ -339,6 +342,9 @@ function ByAgentView({
|
|
|
339
342
|
variant="primary"
|
|
340
343
|
/>
|
|
341
344
|
)}
|
|
345
|
+
{!agent.installed && (
|
|
346
|
+
<span className="text-2xs text-muted-foreground/60">or CLI Skill</span>
|
|
347
|
+
)}
|
|
342
348
|
</div>
|
|
343
349
|
</div>
|
|
344
350
|
|
|
@@ -380,7 +386,7 @@ function ByServerView({
|
|
|
380
386
|
onReconnect: (agent: ReturnType<typeof sortAgentsByStatus>[number]) => Promise<void>;
|
|
381
387
|
}) {
|
|
382
388
|
const [pickerServer, setPickerServer] = useState<string | null>(null);
|
|
383
|
-
const [confirmState, setConfirmState] = useState<{ agentName: string; serverName: string } | null>(null);
|
|
389
|
+
const [confirmState, setConfirmState] = useState<{ agentKey: string; agentName: string; serverName: string } | null>(null);
|
|
384
390
|
const [hintMessage, setHintMessage] = useState<string | null>(null);
|
|
385
391
|
const [reconnectingServer, setReconnectingServer] = useState<string | null>(null);
|
|
386
392
|
const [reconnectMsg, setReconnectMsg] = useState<Record<string, string>>({});
|
|
@@ -393,11 +399,27 @@ function ByServerView({
|
|
|
393
399
|
[onInstallMindos],
|
|
394
400
|
);
|
|
395
401
|
|
|
396
|
-
const handleConfirmRemove = useCallback(() => {
|
|
402
|
+
const handleConfirmRemove = useCallback(async () => {
|
|
403
|
+
if (!confirmState) return;
|
|
404
|
+
const { agentKey } = confirmState;
|
|
397
405
|
setConfirmState(null);
|
|
398
|
-
|
|
406
|
+
|
|
407
|
+
// Find agent info to determine scope
|
|
408
|
+
const agent = allAgents.find(a => a.key === agentKey);
|
|
409
|
+
const scope = agent?.scope === 'project' ? 'project' : 'global';
|
|
410
|
+
|
|
411
|
+
try {
|
|
412
|
+
await apiFetch('/api/mcp/uninstall', {
|
|
413
|
+
method: 'POST',
|
|
414
|
+
headers: { 'Content-Type': 'application/json' },
|
|
415
|
+
body: JSON.stringify({ agents: [{ key: agentKey, scope }] }),
|
|
416
|
+
});
|
|
417
|
+
setHintMessage(copy.removeSuccess ?? 'Removed. Restart your agent to apply.');
|
|
418
|
+
} catch {
|
|
419
|
+
setHintMessage(copy.removeFailed ?? 'Failed to remove. Try editing the config file manually.');
|
|
420
|
+
}
|
|
399
421
|
setTimeout(() => setHintMessage(null), 4000);
|
|
400
|
-
}, [copy
|
|
422
|
+
}, [confirmState, allAgents, copy]);
|
|
401
423
|
|
|
402
424
|
const handleReconnectAllInServer = useCallback(
|
|
403
425
|
async (serverName: string, agents: typeof allAgents) => {
|
|
@@ -517,7 +539,7 @@ function ByServerView({
|
|
|
517
539
|
<AgentAvatar
|
|
518
540
|
name={agent.name}
|
|
519
541
|
status={agentStatus}
|
|
520
|
-
onRemove={() => setConfirmState({ agentName: agent.name, serverName: srv.serverName })}
|
|
542
|
+
onRemove={() => setConfirmState({ agentKey: agent.key, agentName: agent.name, serverName: srv.serverName })}
|
|
521
543
|
/>
|
|
522
544
|
</Link>
|
|
523
545
|
);
|
|
@@ -18,6 +18,7 @@ function Section({ id, icon, title, defaultOpen = false, children }: {
|
|
|
18
18
|
|
|
19
19
|
return (
|
|
20
20
|
<div id={id} className="bg-card border border-border rounded-lg overflow-hidden scroll-mt-4">
|
|
21
|
+
<h2 className="sr-only">{title}</h2>
|
|
21
22
|
<button
|
|
22
23
|
onClick={() => setOpen(v => !v)}
|
|
23
24
|
className="w-full flex items-center gap-3 px-5 py-4 text-left hover:bg-muted/50 transition-colors focus-visible:ring-2 focus-visible:ring-ring"
|