@geminilight/mindos 0.6.50 → 0.6.52
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 +15 -15
- 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 +1 -1
- 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 +2 -2
- 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 +11 -6
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +11 -6
- 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 +6 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +2 -2
- 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 +2 -2
- 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 +31 -31
- 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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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_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 +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 +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 +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_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_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route.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 +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 +2 -2
- 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 +2 -2
- 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/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 +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 +2 -2
- 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 +15 -15
- package/_standalone/.next/server/chunks/2190.js +1 -1
- package/_standalone/.next/server/chunks/2673.js +52 -0
- package/_standalone/.next/server/chunks/4241.js +1 -219
- package/_standalone/.next/server/chunks/8408.js +219 -0
- package/_standalone/.next/server/instrumentation.js +1 -1
- 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/chunks/1053-c519cb347faa75e2.js +29 -0
- package/_standalone/.next/static/chunks/{1814.2ee1d03297c0bccd.js → 1814.72f7fe7c61e2b647.js} +1 -1
- package/_standalone/.next/static/chunks/{1880-c2a9e76201841c86.js → 1880-3ec02adc80531825.js} +1 -1
- package/_standalone/.next/static/chunks/6636-9bbc90fb3b8731fe.js +6 -0
- package/_standalone/.next/static/chunks/7035-032641fb6f4e07b2.js +1 -0
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/_global-error/page-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/{page-773071a99c4daac2.js → page-074d6aafc2606561.js} +1 -1
- package/_standalone/.next/static/chunks/app/agents/{page-0d9920b591ce999f.js → page-710d8c80fa86e93e.js} +2 -2
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/config/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/install/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/session/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/auth/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/backlinks/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/changes/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/export/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/import/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/files/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/git/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/graph/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/health/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/init/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/monitoring/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/recent-files/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/restart/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/search/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/skills/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/sync/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/tree-version/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/uninstall/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-check/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-status/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/api/workflows/route-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/echo/page-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/{layout-5b51589d4eedab68.js → layout-e706f9a963b177ba.js} +20 -20
- package/_standalone/.next/static/chunks/app/loading-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/page-2595175820acfd65.js +7 -0
- package/_standalone/.next/static/chunks/app/setup/page-99f40e9337388cda.js +1 -0
- package/_standalone/.next/static/chunks/app/trash/page-61c6210fac1e9710.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-798359c36f10ef8d.js +12 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-b07a5983e85bc5e3.js +1 -0
- package/_standalone/.next/static/chunks/{webpack-7b276daaa930d480.js → webpack-bbd44cbc83dc0aa4.js} +1 -1
- package/_standalone/.next/static/css/ef1151f74f00d91a.css +1 -0
- package/_standalone/.next/trace +64 -63
- package/_standalone/app/globals.css +1 -1
- package/_standalone/components/ActivityBar.tsx +1 -1
- package/_standalone/components/AskFab.tsx +4 -4
- package/_standalone/components/ExportModal.tsx +4 -1
- package/_standalone/components/FileTree.tsx +13 -5
- package/_standalone/components/Panel.tsx +5 -12
- package/_standalone/components/RightAgentDetailPanel.tsx +5 -4
- package/_standalone/components/RightAskPanel.tsx +5 -4
- package/_standalone/components/agents/AgentsPrimitives.tsx +7 -3
- package/_standalone/components/ask/ProviderModelCapsule.tsx +16 -3
- package/_standalone/components/settings/AiTab.tsx +1 -0
- package/_standalone/components/settings/Primitives.tsx +84 -3
- package/_standalone/instrumentation.ts +3 -1
- package/_standalone/lib/config/animation.ts +76 -0
- package/_standalone/lib/config/icon-scale.ts +35 -0
- package/_standalone/lib/config/panel-sizes.ts +58 -0
- package/_standalone/lib/hooks/useFocusTrap.ts +65 -0
- package/_standalone/lib/i18n/modules/knowledge.ts +16 -8
- package/_standalone/lib/i18n/modules/onboarding.ts +2 -2
- package/_standalone/lib/i18n/modules/settings.ts +4 -0
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/api/ask/route.ts +47 -15
- package/app/app/globals.css +1 -1
- package/app/app/loading.tsx +80 -0
- package/app/app/view/[...path]/loading.tsx +32 -9
- package/app/components/ActivityBar.tsx +1 -1
- package/app/components/AskFab.tsx +4 -4
- package/app/components/ExportModal.tsx +4 -1
- package/app/components/FileTree.tsx +13 -5
- package/app/components/HomeContent.tsx +29 -12
- package/app/components/Panel.tsx +5 -12
- package/app/components/RightAgentDetailPanel.tsx +5 -4
- package/app/components/RightAskPanel.tsx +5 -4
- package/app/components/TrashPageClient.tsx +4 -4
- package/app/components/agents/AgentsPrimitives.tsx +7 -3
- package/app/components/ask/ProviderModelCapsule.tsx +16 -3
- package/app/components/settings/AiTab.tsx +1 -0
- package/app/components/settings/Primitives.tsx +84 -3
- package/app/components/ui/Toaster.tsx +1 -1
- package/app/instrumentation.ts +3 -1
- package/app/lib/config/animation.ts +76 -0
- package/app/lib/config/icon-scale.ts +35 -0
- package/app/lib/config/panel-sizes.ts +58 -0
- package/app/lib/hooks/useFocusTrap.ts +65 -0
- package/app/lib/i18n/modules/knowledge.ts +16 -8
- package/app/lib/i18n/modules/onboarding.ts +2 -2
- package/app/lib/i18n/modules/settings.ts +4 -0
- package/bin/commands/dev.js +10 -0
- package/bin/commands/doctor.js +18 -6
- package/bin/commands/start.js +17 -8
- package/bin/lib/cli-shim.js +166 -0
- package/package.json +1 -1
- package/_standalone/.next/server/chunks/273.js +0 -52
- package/_standalone/.next/server/chunks/6622.js +0 -1
- package/_standalone/.next/static/chunks/1053-8cb7fd1bfbbbedd3.js +0 -29
- package/_standalone/.next/static/chunks/4563-b2a2ce80aff845af.js +0 -6
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/_global-error/page-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/config/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/install/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/session/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/auth/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/backlinks/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/changes/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/export/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/import/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/files/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/git/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/graph/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/health/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/inbox/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/init/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/monitoring/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/recent-files/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/restart/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/search/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/skills/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/sync/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/tree-version/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/uninstall/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-check/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-status/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/api/workflows/route-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/page-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/page-9ba25963d955f3d4.js +0 -7
- package/_standalone/.next/static/chunks/app/setup/page-81c37de31c9a5beb.js +0 -1
- package/_standalone/.next/static/chunks/app/trash/page-20ee39622ea5047a.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-67c4bf985a579c77.js +0 -12
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-84943536516b00b2.js +0 -1
- package/_standalone/.next/static/css/bc9179074eaf65ae.css +0 -1
- /package/_standalone/.next/static/{2qUKZF7S693ZZWFgkTSUY → IiTZbEzZo8l5MSUxlDwKp}/_buildManifest.js +0 -0
- /package/_standalone/.next/static/{2qUKZF7S693ZZWFgkTSUY → IiTZbEzZo8l5MSUxlDwKp}/_ssgManifest.js +0 -0
package/app/app/api/ask/route.ts
CHANGED
|
@@ -230,21 +230,26 @@ function readKnowledgeFile(filePath: string): { ok: boolean; content: string; tr
|
|
|
230
230
|
* Tries in order: app/data/skills → skills → {mindRoot}/.skills → ~/.mindos/skills
|
|
231
231
|
* Returns { path, result } where result is the file content or error.
|
|
232
232
|
*/
|
|
233
|
+
/**
|
|
234
|
+
* Candidate skill directories, ordered by priority.
|
|
235
|
+
* Used for SKILL.md resolution AND reference file fallback.
|
|
236
|
+
*/
|
|
237
|
+
function skillDirCandidates(skillName: string, projectRoot: string, mindRoot: string): string[] {
|
|
238
|
+
return [
|
|
239
|
+
path.join(projectRoot, 'app', 'data', 'skills', skillName),
|
|
240
|
+
path.join(projectRoot, 'skills', skillName),
|
|
241
|
+
path.join(mindRoot, '.skills', skillName),
|
|
242
|
+
path.join(process.env.HOME || '/root', '.mindos', 'skills', skillName),
|
|
243
|
+
];
|
|
244
|
+
}
|
|
245
|
+
|
|
233
246
|
function resolveSkillFile(
|
|
234
247
|
skillName: string,
|
|
235
248
|
projectRoot: string,
|
|
236
249
|
mindRoot: string,
|
|
237
250
|
): { path: string; result: ReturnType<typeof readAbsoluteFile> } {
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
path.join(projectRoot, 'app', 'data', 'skills', skillName, 'SKILL.md'),
|
|
241
|
-
// Fallback: repository root (dev/CLI usage)
|
|
242
|
-
path.join(projectRoot, 'skills', skillName, 'SKILL.md'),
|
|
243
|
-
// Fallback: knowledge base custom skills
|
|
244
|
-
path.join(mindRoot, '.skills', skillName, 'SKILL.md'),
|
|
245
|
-
// Fallback: global user skills
|
|
246
|
-
path.join(process.env.HOME || '/root', '.mindos', 'skills', skillName, 'SKILL.md'),
|
|
247
|
-
];
|
|
251
|
+
const dirs = skillDirCandidates(skillName, projectRoot, mindRoot);
|
|
252
|
+
const locations = dirs.map(d => path.join(d, 'SKILL.md'));
|
|
248
253
|
|
|
249
254
|
for (const absPath of locations) {
|
|
250
255
|
const result = readAbsoluteFile(absPath);
|
|
@@ -253,7 +258,6 @@ function resolveSkillFile(
|
|
|
253
258
|
}
|
|
254
259
|
}
|
|
255
260
|
|
|
256
|
-
// All locations failed — return last error
|
|
257
261
|
return {
|
|
258
262
|
path: locations[locations.length - 1],
|
|
259
263
|
result: {
|
|
@@ -265,6 +269,34 @@ function resolveSkillFile(
|
|
|
265
269
|
};
|
|
266
270
|
}
|
|
267
271
|
|
|
272
|
+
/**
|
|
273
|
+
* Resolve a skill reference file (e.g. references/write-supplement.md) with
|
|
274
|
+
* multi-location fallback. First tries relative to the found SKILL.md, then
|
|
275
|
+
* falls back to all other candidate directories. This handles the case where
|
|
276
|
+
* SKILL.md is found in one location but its references/ dir is in another
|
|
277
|
+
* (e.g. stale Desktop build, Core Hot Update with partial content).
|
|
278
|
+
*/
|
|
279
|
+
function resolveSkillReference(
|
|
280
|
+
relPath: string,
|
|
281
|
+
skillInfo: { path: string },
|
|
282
|
+
skillName: string,
|
|
283
|
+
projectRoot: string,
|
|
284
|
+
mindRoot: string,
|
|
285
|
+
): ReturnType<typeof readAbsoluteFile> {
|
|
286
|
+
const primaryDir = path.dirname(skillInfo.path);
|
|
287
|
+
const primaryPath = path.join(primaryDir, relPath);
|
|
288
|
+
const primaryResult = readAbsoluteFile(primaryPath);
|
|
289
|
+
if (primaryResult.ok) return primaryResult;
|
|
290
|
+
|
|
291
|
+
for (const dir of skillDirCandidates(skillName, projectRoot, mindRoot)) {
|
|
292
|
+
if (dir === primaryDir) continue;
|
|
293
|
+
const result = readAbsoluteFile(path.join(dir, relPath));
|
|
294
|
+
if (result.ok) return result;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return primaryResult;
|
|
298
|
+
}
|
|
299
|
+
|
|
268
300
|
/**
|
|
269
301
|
* In-memory cache for absolute file reads (SKILL.md, etc).
|
|
270
302
|
* Keyed by absPath. Re-reads only when file mtime changes.
|
|
@@ -504,10 +536,10 @@ export async function POST(req: NextRequest) {
|
|
|
504
536
|
const skillInfo = resolveSkillFile(skillDirName, projectRoot, mindRoot);
|
|
505
537
|
const skill = skillInfo.result;
|
|
506
538
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
539
|
+
const skillWrite = resolveSkillReference(
|
|
540
|
+
path.join('references', 'write-supplement.md'),
|
|
541
|
+
skillInfo, skillDirName, projectRoot, mindRoot,
|
|
542
|
+
);
|
|
511
543
|
|
|
512
544
|
console.log(
|
|
513
545
|
`[ask] SKILL skill=${skill.ok} (${skillInfo.path}), write-supplement=${skillWrite.ok}`
|
package/app/app/globals.css
CHANGED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Home page skeleton — shown while server components load.
|
|
3
|
+
* Matches the HomeContent layout: hero → spaces grid → recent files.
|
|
4
|
+
*/
|
|
5
|
+
export default function Loading() {
|
|
6
|
+
return (
|
|
7
|
+
<div className="content-width px-4 md:px-6 py-10 md:py-14 animate-pulse" aria-busy="true" aria-label="Loading">
|
|
8
|
+
{/* Hero skeleton */}
|
|
9
|
+
<div className="mb-10">
|
|
10
|
+
<div className="flex items-center gap-3 mb-2">
|
|
11
|
+
<div className="w-1 h-7 rounded-full bg-muted" />
|
|
12
|
+
<div className="h-6 w-28 bg-muted rounded" />
|
|
13
|
+
</div>
|
|
14
|
+
<div className="h-4 w-64 bg-muted rounded ml-4 mb-6" />
|
|
15
|
+
|
|
16
|
+
{/* Command bar skeleton */}
|
|
17
|
+
<div className="w-full max-w-xl flex flex-col sm:flex-row items-stretch sm:items-center gap-2 ml-4">
|
|
18
|
+
<div className="flex-1 h-12 rounded-xl bg-muted" />
|
|
19
|
+
<div className="h-12 w-16 rounded-xl bg-muted shrink-0" />
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
{/* Quick actions skeleton */}
|
|
23
|
+
<div className="flex items-center gap-3 mt-4 ml-4">
|
|
24
|
+
<div className="h-9 w-28 rounded-lg bg-muted" />
|
|
25
|
+
<div className="h-9 w-40 rounded-lg bg-muted" />
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
{/* Spaces grid skeleton */}
|
|
30
|
+
<div className="mb-10">
|
|
31
|
+
<div className="flex items-center gap-2 mb-4">
|
|
32
|
+
<div className="w-4 h-4 rounded bg-muted" />
|
|
33
|
+
<div className="h-4 w-16 bg-muted rounded" />
|
|
34
|
+
</div>
|
|
35
|
+
<div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
|
|
36
|
+
{Array.from({ length: 6 }).map((_, i) => (
|
|
37
|
+
<div key={i} className="flex items-start gap-3 px-3.5 py-3 rounded-xl border border-border">
|
|
38
|
+
<div className="w-5 h-5 rounded bg-muted shrink-0 mt-0.5" />
|
|
39
|
+
<div className="flex-1 space-y-1.5">
|
|
40
|
+
<div className="h-4 w-20 bg-muted rounded" />
|
|
41
|
+
<div className="h-3 w-full bg-muted rounded" />
|
|
42
|
+
<div className="h-3 w-12 bg-muted rounded" />
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
))}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
{/* Recent files skeleton */}
|
|
50
|
+
<div className="mb-10">
|
|
51
|
+
<div className="flex items-center gap-2 mb-4">
|
|
52
|
+
<div className="w-4 h-4 rounded bg-muted" />
|
|
53
|
+
<div className="h-4 w-24 bg-muted rounded" />
|
|
54
|
+
</div>
|
|
55
|
+
<div className="flex flex-col gap-3">
|
|
56
|
+
{Array.from({ length: 3 }).map((_, i) => (
|
|
57
|
+
<div key={i}>
|
|
58
|
+
<div className="flex items-center gap-2 px-1 py-1.5">
|
|
59
|
+
<div className="w-4 h-4 rounded bg-muted" />
|
|
60
|
+
<div className="h-3 w-24 bg-muted rounded" />
|
|
61
|
+
</div>
|
|
62
|
+
<div className="flex flex-col gap-0.5 ml-2 border-l border-border/40 pl-3">
|
|
63
|
+
{Array.from({ length: 2 }).map((_, j) => (
|
|
64
|
+
<div key={j} className="flex items-center gap-3 px-3 py-2">
|
|
65
|
+
<div className="w-3 h-3 rounded bg-muted shrink-0" />
|
|
66
|
+
<div className="flex-1 space-y-1">
|
|
67
|
+
<div className="h-4 w-40 bg-muted rounded" />
|
|
68
|
+
<div className="h-3 w-24 bg-muted rounded" />
|
|
69
|
+
</div>
|
|
70
|
+
<div className="h-3 w-12 bg-muted rounded shrink-0" />
|
|
71
|
+
</div>
|
|
72
|
+
))}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
))}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
@@ -1,14 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File viewer skeleton — shown while file content loads.
|
|
3
|
+
* Matches the prose layout with heading + paragraph blocks.
|
|
4
|
+
*/
|
|
1
5
|
export default function Loading() {
|
|
2
6
|
return (
|
|
3
|
-
<div className="
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
<div className="content-width px-4 md:px-6 py-10 md:py-14 animate-pulse" aria-busy="true" aria-label="Loading">
|
|
8
|
+
{/* Title skeleton */}
|
|
9
|
+
<div className="h-8 w-64 bg-muted rounded mb-3" />
|
|
10
|
+
<div className="h-px w-full bg-border mb-8" />
|
|
11
|
+
|
|
12
|
+
{/* Paragraph skeletons */}
|
|
13
|
+
<div className="space-y-6">
|
|
14
|
+
{Array.from({ length: 4 }).map((_, i) => (
|
|
15
|
+
<div key={i} className="space-y-2">
|
|
16
|
+
{i % 2 === 0 && <div className="h-5 w-40 bg-muted rounded mb-3" />}
|
|
17
|
+
<div className="h-3.5 w-full bg-muted rounded" />
|
|
18
|
+
<div className="h-3.5 w-full bg-muted rounded" />
|
|
19
|
+
<div className="h-3.5 w-3/4 bg-muted rounded" />
|
|
20
|
+
</div>
|
|
21
|
+
))}
|
|
22
|
+
|
|
23
|
+
{/* Code block skeleton */}
|
|
24
|
+
<div className="rounded-lg border border-border p-4 space-y-2">
|
|
25
|
+
<div className="h-3 w-48 bg-muted rounded" />
|
|
26
|
+
<div className="h-3 w-64 bg-muted rounded" />
|
|
27
|
+
<div className="h-3 w-36 bg-muted rounded" />
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
{/* More paragraphs */}
|
|
31
|
+
<div className="space-y-2">
|
|
32
|
+
<div className="h-3.5 w-full bg-muted rounded" />
|
|
33
|
+
<div className="h-3.5 w-5/6 bg-muted rounded" />
|
|
34
|
+
</div>
|
|
12
35
|
</div>
|
|
13
36
|
</div>
|
|
14
37
|
);
|
|
@@ -48,7 +48,7 @@ function RailButton({ icon, label, shortcut, active = false, expanded, onClick,
|
|
|
48
48
|
onClick={onClick}
|
|
49
49
|
aria-pressed={active}
|
|
50
50
|
aria-label={label}
|
|
51
|
-
title={
|
|
51
|
+
title={shortcut ? `${label} (${shortcut})` : label}
|
|
52
52
|
data-walkthrough={walkthroughId}
|
|
53
53
|
className={`
|
|
54
54
|
relative flex items-center ${expanded ? 'justify-start px-3 w-full' : 'justify-center w-10'} h-10 rounded-md transition-colors
|
|
@@ -22,16 +22,16 @@ export default function AskFab({ onToggle, askPanelOpen }: AskFabProps) {
|
|
|
22
22
|
fixed z-40 bottom-5 right-5
|
|
23
23
|
items-center justify-center
|
|
24
24
|
gap-0 hover:gap-2
|
|
25
|
-
p-
|
|
25
|
+
p-3 rounded-xl
|
|
26
26
|
text-white font-medium text-[13px]
|
|
27
|
-
shadow-
|
|
27
|
+
shadow-sm shadow-amber-900/10
|
|
28
28
|
transition-all duration-200 ease-out
|
|
29
|
-
hover:shadow-
|
|
29
|
+
hover:shadow-md hover:shadow-amber-900/15
|
|
30
30
|
active:scale-95 cursor-pointer overflow-hidden font-display
|
|
31
31
|
${askPanelOpen ? 'opacity-0 pointer-events-none translate-y-2' : 'opacity-100 translate-y-0'}
|
|
32
32
|
`}
|
|
33
33
|
style={{
|
|
34
|
-
background: '
|
|
34
|
+
background: 'var(--amber)',
|
|
35
35
|
}}
|
|
36
36
|
title={label}
|
|
37
37
|
aria-label={label}
|
|
@@ -104,13 +104,16 @@ export default function ExportModal({ open, onClose, filePath, isDirectory, file
|
|
|
104
104
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm" onClick={state === 'exporting' ? undefined : handleClose}>
|
|
105
105
|
<div
|
|
106
106
|
className="bg-card border border-border rounded-xl shadow-xl max-w-md w-full mx-4 animate-in fade-in-0 zoom-in-95 duration-200"
|
|
107
|
+
role="dialog"
|
|
108
|
+
aria-modal="true"
|
|
109
|
+
aria-labelledby="export-modal-title"
|
|
107
110
|
onClick={e => e.stopPropagation()}
|
|
108
111
|
>
|
|
109
112
|
{/* Header */}
|
|
110
113
|
<div className="flex items-center justify-between px-5 py-4 border-b border-border">
|
|
111
114
|
<div className="flex items-center gap-2">
|
|
112
115
|
<Download size={15} className="text-[var(--amber)]" />
|
|
113
|
-
<h3 className="text-sm font-semibold font-display">
|
|
116
|
+
<h3 id="export-modal-title" className="text-sm font-semibold font-display">
|
|
114
117
|
{isDirectory ? (t.export?.exportSpace ?? 'Export Space') : (t.export?.exportFile ?? 'Export File')}
|
|
115
118
|
</h3>
|
|
116
119
|
</div>
|
|
@@ -4,6 +4,7 @@ import { useState, useCallback, useRef, useTransition, useEffect, useSyncExterna
|
|
|
4
4
|
import { useRouter, usePathname } from 'next/navigation';
|
|
5
5
|
import { FileNode, SYSTEM_FILES, UNDELETABLE_FILES } from '@/lib/types';
|
|
6
6
|
import { encodePath } from '@/lib/utils';
|
|
7
|
+
import { ICON_SIZES } from '@/lib/config/icon-scale';
|
|
7
8
|
import {
|
|
8
9
|
ChevronDown, FileText, Table, Folder, FolderOpen, Plus, Loader2,
|
|
9
10
|
Trash2, Pencil, Layers, ScrollText, FolderInput, Copy, MoreHorizontal, Star, Inbox,
|
|
@@ -61,8 +62,8 @@ interface FileTreeProps {
|
|
|
61
62
|
|
|
62
63
|
function getIcon(node: FileNode) {
|
|
63
64
|
if (node.type === 'directory') return null;
|
|
64
|
-
if (node.extension === '.csv') return <Table size={
|
|
65
|
-
return <FileText size={
|
|
65
|
+
if (node.extension === '.csv') return <Table size={ICON_SIZES.md} className="text-success shrink-0" />;
|
|
66
|
+
return <FileText size={ICON_SIZES.md} className="text-muted-foreground shrink-0" />;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
function getCurrentFilePath(pathname: string): string {
|
|
@@ -428,9 +429,10 @@ function DirectoryNode({ node, depth, currentPath, onNavigate, maxOpenDepth, onI
|
|
|
428
429
|
className="shrink-0 p-1 rounded hover:bg-muted text-muted-foreground transition-colors"
|
|
429
430
|
style={{ marginLeft: `${depth * 12 + 4}px` }}
|
|
430
431
|
aria-label={open ? `Collapse ${node.name}` : `Expand ${node.name}`}
|
|
432
|
+
aria-expanded={open}
|
|
431
433
|
>
|
|
432
434
|
<span className="block transition-transform duration-150" style={{ transform: open ? 'rotate(0deg)' : 'rotate(-90deg)' }}>
|
|
433
|
-
<ChevronDown size={
|
|
435
|
+
<ChevronDown size={ICON_SIZES.xs} />
|
|
434
436
|
</span>
|
|
435
437
|
</button>
|
|
436
438
|
<button
|
|
@@ -446,7 +448,7 @@ function DirectoryNode({ node, depth, currentPath, onNavigate, maxOpenDepth, onI
|
|
|
446
448
|
className={`
|
|
447
449
|
flex-1 flex items-center gap-1.5 px-1 py-1 rounded text-left min-w-0 pr-16
|
|
448
450
|
text-sm transition-colors duration-100
|
|
449
|
-
hover:bg-muted
|
|
451
|
+
hover:bg-muted cursor-text
|
|
450
452
|
${isActive ? 'text-foreground' : 'text-muted-foreground hover:text-foreground'}
|
|
451
453
|
`}
|
|
452
454
|
>
|
|
@@ -459,6 +461,9 @@ function DirectoryNode({ node, depth, currentPath, onNavigate, maxOpenDepth, onI
|
|
|
459
461
|
: <Folder size={14} className="text-yellow-400 shrink-0" />
|
|
460
462
|
}
|
|
461
463
|
<span className="truncate leading-5" suppressHydrationWarning>{node.name}</span>
|
|
464
|
+
<span className="ml-auto text-xs text-muted-foreground/30 group-hover/dir:text-muted-foreground/60 transition-colors shrink-0 hidden group-hover/dir:inline-flex items-center gap-1">
|
|
465
|
+
<Pencil size={10} />
|
|
466
|
+
</span>
|
|
462
467
|
{isSpace && !open && (
|
|
463
468
|
<span className="ml-auto text-xs text-muted-foreground shrink-0 tabular-nums pr-1">{contentCount}</span>
|
|
464
469
|
)}
|
|
@@ -659,7 +664,7 @@ function FileNodeItem({ node, depth, currentPath, onNavigate }: {
|
|
|
659
664
|
data-filepath={node.path}
|
|
660
665
|
className={`
|
|
661
666
|
w-full flex items-center gap-1.5 px-2 py-1 rounded text-left
|
|
662
|
-
text-sm transition-colors duration-100 cursor-
|
|
667
|
+
text-sm transition-colors duration-100 cursor-text pr-16
|
|
663
668
|
${isActive
|
|
664
669
|
? 'bg-accent text-foreground'
|
|
665
670
|
: 'hover:bg-muted text-muted-foreground hover:text-foreground'
|
|
@@ -669,6 +674,9 @@ function FileNodeItem({ node, depth, currentPath, onNavigate }: {
|
|
|
669
674
|
>
|
|
670
675
|
{getIcon(node)}
|
|
671
676
|
<span className="truncate leading-5" suppressHydrationWarning>{node.name}</span>
|
|
677
|
+
<span className="ml-auto text-xs text-muted-foreground/30 group-hover/file:text-muted-foreground/60 transition-colors shrink-0 hidden group-hover/file:inline-flex items-center gap-1">
|
|
678
|
+
<Pencil size={10} />
|
|
679
|
+
</span>
|
|
672
680
|
{pinned && <Star size={10} className="shrink-0 fill-[var(--amber)] text-[var(--amber)] opacity-60" />}
|
|
673
681
|
</button>
|
|
674
682
|
<div className="absolute right-1 top-1/2 -translate-y-1/2 hidden group-hover/file:flex items-center gap-0.5">
|
|
@@ -123,7 +123,7 @@ function FileRow({ filePath, mtime, formatTime, subPath }: {
|
|
|
123
123
|
return (
|
|
124
124
|
<Link
|
|
125
125
|
href={`/view/${encodePath(filePath)}`}
|
|
126
|
-
className="flex items-center gap-3 px-3 py-2 rounded-lg transition-all duration-100 hover:translate-x-0.5 hover:bg-muted group"
|
|
126
|
+
className="flex items-center gap-3 px-3 py-2 rounded-lg transition-all duration-100 hover:translate-x-0.5 hover:bg-muted group overflow-hidden"
|
|
127
127
|
>
|
|
128
128
|
{isCSV
|
|
129
129
|
? <Table size={12} className="shrink-0 text-success" />
|
|
@@ -200,7 +200,7 @@ export default function HomeContent({ recent, existingFiles, spaces }: { recent:
|
|
|
200
200
|
data-walkthrough="ask-button"
|
|
201
201
|
className="flex-1 flex items-center gap-3 px-4 py-3 rounded-xl border border-border/60 shadow-sm bg-card transition-all duration-150 hover:border-[var(--amber)]/50 hover:shadow-md group"
|
|
202
202
|
>
|
|
203
|
-
<Sparkles size={
|
|
203
|
+
<Sparkles size={16} className="shrink-0 text-[var(--amber)] group-hover:scale-110 transition-transform duration-150" />
|
|
204
204
|
<div className="flex-1 min-h-[1.5rem] flex items-center">
|
|
205
205
|
<span
|
|
206
206
|
key={suggestionIdx}
|
|
@@ -219,7 +219,7 @@ export default function HomeContent({ recent, existingFiles, spaces }: { recent:
|
|
|
219
219
|
className="flex items-center gap-2 px-3.5 py-3 rounded-xl border border-border/60 text-sm text-muted-foreground transition-all duration-150 shrink-0 hover:bg-muted hover:shadow-sm"
|
|
220
220
|
>
|
|
221
221
|
<Search size={14} />
|
|
222
|
-
<kbd className="hidden sm:inline-flex items-center px-1.5 py-0.5 rounded text-
|
|
222
|
+
<kbd className="hidden sm:inline-flex items-center px-1.5 py-0.5 rounded text-xs font-mono bg-muted">
|
|
223
223
|
⌘K
|
|
224
224
|
</kbd>
|
|
225
225
|
</button>
|
|
@@ -264,7 +264,7 @@ export default function HomeContent({ recent, existingFiles, spaces }: { recent:
|
|
|
264
264
|
{(spaceList.length > 0 || true) && (
|
|
265
265
|
<section className="mb-10">
|
|
266
266
|
<SectionTitle
|
|
267
|
-
icon={<Brain size={
|
|
267
|
+
icon={<Brain size={14} />}
|
|
268
268
|
count={spaceList.length > 0 ? spaceList.length : undefined}
|
|
269
269
|
action={<CreateSpaceButton t={t} />}
|
|
270
270
|
>
|
|
@@ -330,7 +330,7 @@ export default function HomeContent({ recent, existingFiles, spaces }: { recent:
|
|
|
330
330
|
{recent.length > 0 && (
|
|
331
331
|
<section className="mb-10">
|
|
332
332
|
<SectionTitle
|
|
333
|
-
icon={<Clock size={
|
|
333
|
+
icon={<Clock size={14} />}
|
|
334
334
|
count={recent.length}
|
|
335
335
|
action={
|
|
336
336
|
<Link
|
|
@@ -356,7 +356,7 @@ export default function HomeContent({ recent, existingFiles, spaces }: { recent:
|
|
|
356
356
|
href={`/view/${encodePath(group.spacePath)}`}
|
|
357
357
|
className="flex items-center gap-2 px-1 py-1.5 rounded-lg group transition-colors hover:bg-muted/50"
|
|
358
358
|
>
|
|
359
|
-
<Folder size={
|
|
359
|
+
<Folder size={14} className="shrink-0 text-[var(--amber)]" />
|
|
360
360
|
<span className="text-xs font-semibold font-display text-foreground group-hover:text-[var(--amber)] transition-colors" suppressHydrationWarning>
|
|
361
361
|
{group.space}
|
|
362
362
|
</span>
|
|
@@ -387,7 +387,7 @@ export default function HomeContent({ recent, existingFiles, spaces }: { recent:
|
|
|
387
387
|
{rootFiles.length > 0 && (
|
|
388
388
|
<div>
|
|
389
389
|
<div className="flex items-center gap-2 px-1 py-1.5">
|
|
390
|
-
<FileText size={
|
|
390
|
+
<FileText size={14} className="shrink-0 text-muted-foreground/50" />
|
|
391
391
|
<span className="text-xs font-semibold font-display text-muted-foreground/60">
|
|
392
392
|
{t.home.other}
|
|
393
393
|
</span>
|
|
@@ -430,7 +430,7 @@ export default function HomeContent({ recent, existingFiles, spaces }: { recent:
|
|
|
430
430
|
/>
|
|
431
431
|
<Link
|
|
432
432
|
href={`/view/${encodePath(filePath)}`}
|
|
433
|
-
className="flex items-center gap-3 px-3 py-2 rounded-lg transition-all duration-100 group-hover:translate-x-0.5 hover:bg-muted"
|
|
433
|
+
className="flex items-center gap-3 px-3 py-2 rounded-lg transition-all duration-100 group-hover:translate-x-0.5 hover:bg-muted overflow-hidden"
|
|
434
434
|
>
|
|
435
435
|
{isCSV
|
|
436
436
|
? <Table size={12} className="shrink-0 text-success" />
|
|
@@ -476,11 +476,28 @@ function PinnedFilesSection({ formatTime }: { formatTime: (t: number) => string
|
|
|
476
476
|
const { t } = useLocale();
|
|
477
477
|
const { pinnedFiles, removePin } = usePinnedFiles();
|
|
478
478
|
|
|
479
|
-
if (pinnedFiles.length === 0)
|
|
479
|
+
if (pinnedFiles.length === 0) {
|
|
480
|
+
return (
|
|
481
|
+
<section className="mb-12">
|
|
482
|
+
<SectionTitle icon={<Star size={14} />}>
|
|
483
|
+
{t.pinnedFiles.title}
|
|
484
|
+
</SectionTitle>
|
|
485
|
+
<div className="py-6 px-4 rounded-lg border border-dashed border-border/50 text-center">
|
|
486
|
+
<Star size={20} className="mx-auto mb-2 text-muted-foreground/40" />
|
|
487
|
+
<p className="text-sm font-medium text-muted-foreground mb-1">
|
|
488
|
+
{t.pinnedFiles.empty ?? 'No pinned files'}
|
|
489
|
+
</p>
|
|
490
|
+
<p className="text-xs text-muted-foreground/60">
|
|
491
|
+
{t.pinnedFiles.emptyHint ?? 'Click the star icon on any file to pin it here'}
|
|
492
|
+
</p>
|
|
493
|
+
</div>
|
|
494
|
+
</section>
|
|
495
|
+
);
|
|
496
|
+
}
|
|
480
497
|
|
|
481
498
|
return (
|
|
482
499
|
<section className="mb-12">
|
|
483
|
-
<SectionTitle icon={<Star size={
|
|
500
|
+
<SectionTitle icon={<Star size={14} />} count={pinnedFiles.length}>
|
|
484
501
|
{t.pinnedFiles.title}
|
|
485
502
|
</SectionTitle>
|
|
486
503
|
<div className="flex flex-col gap-0.5">
|
|
@@ -492,7 +509,7 @@ function PinnedFilesSection({ formatTime }: { formatTime: (t: number) => string
|
|
|
492
509
|
<div key={filePath} className="group/pin relative">
|
|
493
510
|
<Link
|
|
494
511
|
href={`/view/${encodePath(filePath)}`}
|
|
495
|
-
className="flex items-center gap-3 px-3 py-2 rounded-lg transition-all duration-100 hover:translate-x-0.5 hover:bg-muted"
|
|
512
|
+
className="flex items-center gap-3 px-3 py-2 rounded-lg transition-all duration-100 hover:translate-x-0.5 hover:bg-muted overflow-hidden"
|
|
496
513
|
>
|
|
497
514
|
<Star size={12} className="shrink-0 fill-[var(--amber)] text-[var(--amber)]" />
|
|
498
515
|
{isCSV
|
|
@@ -581,7 +598,7 @@ function ExampleCleanupBanner() {
|
|
|
581
598
|
disabled={cleaning}
|
|
582
599
|
className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg transition-colors shrink-0 disabled:opacity-50 bg-[var(--amber-dim)] text-[var(--amber-text)] hover:opacity-80"
|
|
583
600
|
>
|
|
584
|
-
{cleaning ? <Loader2 size={
|
|
601
|
+
{cleaning ? <Loader2 size={12} className="animate-spin" /> : <Trash2 size={12} />}
|
|
585
602
|
{t.home.cleanupExamplesButton}
|
|
586
603
|
</button>
|
|
587
604
|
<button
|
package/app/components/Panel.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import PanelHeader from './panels/PanelHeader';
|
|
|
11
11
|
import { useResizeDrag } from '@/hooks/useResizeDrag';
|
|
12
12
|
import { useLocale } from '@/lib/stores/locale-store';
|
|
13
13
|
import { listTrashAction } from '@/lib/actions';
|
|
14
|
+
import { DEFAULT_LEFT_PANEL_WIDTH, LEFT_PANEL } from '@/lib/config/panel-sizes';
|
|
14
15
|
|
|
15
16
|
const noop = () => {};
|
|
16
17
|
|
|
@@ -25,18 +26,10 @@ function getMaxDepth(nodes: FileNode[], current = 0): number {
|
|
|
25
26
|
return max;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
const DEFAULT_PANEL_WIDTH
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
agents: 280,
|
|
33
|
-
discover: 280,
|
|
34
|
-
workflows: 280,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const MIN_PANEL_WIDTH = 240;
|
|
38
|
-
const MAX_PANEL_WIDTH_RATIO = 0.45;
|
|
39
|
-
const MAX_PANEL_WIDTH_ABS = 600;
|
|
29
|
+
const DEFAULT_PANEL_WIDTH = DEFAULT_LEFT_PANEL_WIDTH;
|
|
30
|
+
const MIN_PANEL_WIDTH = LEFT_PANEL.MIN;
|
|
31
|
+
const MAX_PANEL_WIDTH_RATIO = LEFT_PANEL.MAX_RATIO;
|
|
32
|
+
const MAX_PANEL_WIDTH_ABS = LEFT_PANEL.MAX_ABS;
|
|
40
33
|
|
|
41
34
|
interface PanelProps {
|
|
42
35
|
activePanel: PanelId | null;
|
|
@@ -6,11 +6,12 @@ import { useLocale } from '@/lib/stores/locale-store';
|
|
|
6
6
|
import { useResizeDrag } from '@/hooks/useResizeDrag';
|
|
7
7
|
import AgentsPanelAgentDetail from '@/components/panels/AgentsPanelAgentDetail';
|
|
8
8
|
import { resolveAgentDetailStatus } from '@/components/panels/agents-panel-resolve-status';
|
|
9
|
+
import { RIGHT_AGENT_DETAIL_PANEL } from '@/lib/config/panel-sizes';
|
|
9
10
|
|
|
10
|
-
const DEFAULT_WIDTH =
|
|
11
|
-
const MIN_WIDTH =
|
|
12
|
-
const MAX_WIDTH_ABS =
|
|
13
|
-
const MAX_WIDTH_RATIO =
|
|
11
|
+
const DEFAULT_WIDTH = RIGHT_AGENT_DETAIL_PANEL.DEFAULT;
|
|
12
|
+
const MIN_WIDTH = RIGHT_AGENT_DETAIL_PANEL.MIN;
|
|
13
|
+
const MAX_WIDTH_ABS = RIGHT_AGENT_DETAIL_PANEL.MAX_ABS;
|
|
14
|
+
const MAX_WIDTH_RATIO = RIGHT_AGENT_DETAIL_PANEL.MAX_RATIO;
|
|
14
15
|
|
|
15
16
|
interface RightAgentDetailPanelProps {
|
|
16
17
|
open: boolean;
|
|
@@ -5,13 +5,14 @@ import { AlertCircle } from 'lucide-react';
|
|
|
5
5
|
import AskContent from '@/components/ask/AskContent';
|
|
6
6
|
import ErrorBoundary from '@/components/ErrorBoundary';
|
|
7
7
|
import { useResizeDrag } from '@/hooks/useResizeDrag';
|
|
8
|
+
import { RIGHT_ASK_PANEL } from '@/lib/config/panel-sizes';
|
|
8
9
|
|
|
9
|
-
const DEFAULT_WIDTH =
|
|
10
|
-
const MIN_WIDTH =
|
|
11
|
-
const MAX_WIDTH_ABS =
|
|
10
|
+
const DEFAULT_WIDTH = RIGHT_ASK_PANEL.DEFAULT;
|
|
11
|
+
const MIN_WIDTH = RIGHT_ASK_PANEL.MIN;
|
|
12
|
+
const MAX_WIDTH_ABS = RIGHT_ASK_PANEL.MAX_ABS;
|
|
12
13
|
const ENTER_SNAP_THRESHOLD = 80;
|
|
13
14
|
const EXIT_SNAP_THRESHOLD = 16;
|
|
14
|
-
const MIN_CONTENT_WIDTH =
|
|
15
|
+
const MIN_CONTENT_WIDTH = RIGHT_ASK_PANEL.MIN_CONTENT;
|
|
15
16
|
|
|
16
17
|
import type { AcpAgentSelection } from '@/hooks/useAskModal';
|
|
17
18
|
|
|
@@ -45,7 +45,7 @@ export default function TrashPageClient({ initialItems }: { initialItems: TrashM
|
|
|
45
45
|
} else if (result.conflict) {
|
|
46
46
|
setConflictItem(item);
|
|
47
47
|
} else {
|
|
48
|
-
toast.error(result.error ??
|
|
48
|
+
toast.error(result.error ?? t.trash.restoreFailed);
|
|
49
49
|
}
|
|
50
50
|
} finally {
|
|
51
51
|
setBusyId(null);
|
|
@@ -61,7 +61,7 @@ export default function TrashPageClient({ initialItems }: { initialItems: TrashM
|
|
|
61
61
|
setConflictItem(null);
|
|
62
62
|
router.refresh();
|
|
63
63
|
} else {
|
|
64
|
-
toast.error(result.error ??
|
|
64
|
+
toast.error(result.error ?? t.trash.restoreFailed);
|
|
65
65
|
}
|
|
66
66
|
}, [conflictItem, t, router]);
|
|
67
67
|
|
|
@@ -72,7 +72,7 @@ export default function TrashPageClient({ initialItems }: { initialItems: TrashM
|
|
|
72
72
|
setItems(prev => prev.filter(i => i.id !== confirmDelete.id));
|
|
73
73
|
toast.success(t.trash.deleted);
|
|
74
74
|
} else {
|
|
75
|
-
toast.error(result.error ??
|
|
75
|
+
toast.error(result.error ?? t.trash.deleteFailed);
|
|
76
76
|
}
|
|
77
77
|
setConfirmDelete(null);
|
|
78
78
|
}, [confirmDelete, t]);
|
|
@@ -84,7 +84,7 @@ export default function TrashPageClient({ initialItems }: { initialItems: TrashM
|
|
|
84
84
|
setItems([]);
|
|
85
85
|
toast.success(t.trash.emptied(result.count ?? 0));
|
|
86
86
|
} else {
|
|
87
|
-
toast.error(result.error ??
|
|
87
|
+
toast.error(result.error ?? t.trash.emptyFailed);
|
|
88
88
|
}
|
|
89
89
|
setConfirmEmpty(false);
|
|
90
90
|
});
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Loader2, Plus, X } from 'lucide-react';
|
|
4
4
|
import { useEffect, useRef } from 'react';
|
|
5
|
+
import { useFocusTrap } from '@/lib/hooks/useFocusTrap';
|
|
5
6
|
|
|
6
7
|
/* ────────── Pill / Status / Search ────────── */
|
|
7
8
|
|
|
@@ -243,6 +244,9 @@ export function ConfirmDialog({
|
|
|
243
244
|
variant?: 'destructive' | 'default';
|
|
244
245
|
}) {
|
|
245
246
|
const cancelRef = useRef<HTMLButtonElement>(null);
|
|
247
|
+
const dialogRef = useRef<HTMLDivElement>(null);
|
|
248
|
+
|
|
249
|
+
useFocusTrap(dialogRef, open);
|
|
246
250
|
|
|
247
251
|
useEffect(() => {
|
|
248
252
|
if (open) cancelRef.current?.focus();
|
|
@@ -260,10 +264,10 @@ export function ConfirmDialog({
|
|
|
260
264
|
if (!open) return null;
|
|
261
265
|
|
|
262
266
|
return (
|
|
263
|
-
<div className="fixed inset-0 z-50 flex items-center justify-center" role="alertdialog" aria-modal="true" aria-
|
|
267
|
+
<div className="fixed inset-0 z-50 flex items-center justify-center" role="alertdialog" aria-modal="true" aria-labelledby="confirm-dialog-title">
|
|
264
268
|
<div className="absolute inset-0 overlay-backdrop" onClick={onCancel} aria-hidden="true" />
|
|
265
|
-
<div className="relative bg-card border border-border rounded-lg shadow-xl p-5 max-w-sm w-full mx-4 animate-in fade-in zoom-in-95 duration-200">
|
|
266
|
-
<h3 className="text-sm font-medium text-foreground mb-1.5">{title}</h3>
|
|
269
|
+
<div ref={dialogRef} className="relative bg-card border border-border rounded-lg shadow-xl p-5 max-w-sm w-full mx-4 animate-in fade-in zoom-in-95 duration-200">
|
|
270
|
+
<h3 id="confirm-dialog-title" className="text-sm font-medium text-foreground mb-1.5">{title}</h3>
|
|
267
271
|
<p className="text-sm text-muted-foreground mb-4 leading-relaxed">{message}</p>
|
|
268
272
|
<div className="flex justify-end gap-2">
|
|
269
273
|
<button
|
|
@@ -29,7 +29,7 @@ interface DropdownPos {
|
|
|
29
29
|
interface SettingsData {
|
|
30
30
|
ai?: {
|
|
31
31
|
provider?: string;
|
|
32
|
-
providers?: Record<string, { apiKey?: string; model?: string }>;
|
|
32
|
+
providers?: Record<string, { apiKey?: string; model?: string; baseUrl?: string }>;
|
|
33
33
|
};
|
|
34
34
|
envOverrides?: Record<string, boolean>;
|
|
35
35
|
}
|
|
@@ -55,7 +55,8 @@ export function persistProvider(provider: ProviderId | null): void {
|
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Determine which providers are configured (have an API key set via settings or env).
|
|
58
|
-
* Providers with apiKeyFallback (e.g. Ollama)
|
|
58
|
+
* Providers with apiKeyFallback (e.g. Ollama) only appear if the user has explicitly
|
|
59
|
+
* configured them — having an API key, env var, or a saved model/baseUrl entry.
|
|
59
60
|
*/
|
|
60
61
|
function getConfiguredProviders(data: SettingsData): ProviderId[] {
|
|
61
62
|
const result: ProviderId[] = [];
|
|
@@ -67,7 +68,19 @@ function getConfiguredProviders(data: SettingsData): ProviderId[] {
|
|
|
67
68
|
const hasSettingsKey = providers[id]?.apiKey === '***set***';
|
|
68
69
|
const envVar = getApiKeyEnvVar(id);
|
|
69
70
|
const hasEnvKey = envVar ? !!env[envVar] : false;
|
|
70
|
-
|
|
71
|
+
|
|
72
|
+
if (hasSettingsKey || hasEnvKey) {
|
|
73
|
+
result.push(id);
|
|
74
|
+
} else if (preset.apiKeyFallback) {
|
|
75
|
+
// Local providers (Ollama etc.): only show if user has explicitly configured
|
|
76
|
+
// them (selected as default, or saved a model/baseUrl), not just because
|
|
77
|
+
// a fallback key exists and they haven't been touched.
|
|
78
|
+
const isDefault = data.ai?.provider === id;
|
|
79
|
+
const cfg = providers[id];
|
|
80
|
+
if (isDefault || (cfg && (cfg.model || cfg.baseUrl))) {
|
|
81
|
+
result.push(id);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
71
84
|
}
|
|
72
85
|
return result;
|
|
73
86
|
}
|