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