@geminilight/mindos 0.6.58 → 0.6.60
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 +23 -22
- 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/routes-manifest.json +6 -0
- package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +1 -1
- package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/page.js +2 -2
- package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/copy-skill/route.js +1 -0
- package/_standalone/.next/server/app/api/agents/copy-skill/route.js.nft.json +1 -0
- package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -0
- package/_standalone/.next/server/app/api/agents/custom/detect/route.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/route.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js +18 -7
- 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_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +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.js +2 -2
- package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +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_client-reference-manifest.js +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_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_client-reference-manifest.js +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_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_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_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_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 +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/inbox/history/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 -8
- 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 -2
- package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +23 -22
- package/_standalone/.next/server/chunks/1550.js +1 -1
- package/_standalone/.next/server/chunks/3484.js +1 -1
- package/_standalone/.next/server/chunks/530.js +70 -71
- package/_standalone/.next/server/chunks/{6793.js → 9753.js} +2 -2
- package/_standalone/.next/server/chunks/9787.js +2 -0
- package/_standalone/.next/server/middleware-build-manifest.js +1 -1
- package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/_standalone/.next/server/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/K3wZNf5bj_AFYwtqcRXIf/_buildManifest.js +1 -0
- package/_standalone/.next/static/chunks/1369-7d0ac5d1564eed1e.js +1 -0
- package/_standalone/.next/static/chunks/{1814.a7c127b2c73d1f70.js → 1814.a79b84d37df75c43.js} +1 -1
- package/_standalone/.next/static/chunks/3427-2e61a5df1f5e55fb.js +1 -0
- package/_standalone/.next/static/chunks/{1053-fe009233cff06e72.js → 5581-974dfb26d1d1b38f.js} +3 -3
- package/_standalone/.next/static/chunks/6297-085daa21037d5f81.js +1 -0
- package/_standalone/.next/static/chunks/7249-b0a9c77b9a84b11c.js +11 -0
- package/_standalone/.next/static/chunks/7637-904b0a381dc3ec02.js +1 -0
- package/_standalone/.next/static/chunks/8520-76d1b05072178b43.js +22 -0
- package/_standalone/.next/static/chunks/9186-ead47513192f658b.js +1 -0
- package/_standalone/.next/static/chunks/9905-a19d379cb225246e.js +1 -0
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/{route-2f4705aa66819b86.js → route-2ceea6eabf25b1f2.js} +1 -1
- package/_standalone/.next/static/chunks/app/_global-error/{page-2f4705aa66819b86.js → page-2ceea6eabf25b1f2.js} +1 -1
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-0ea3571c8fbae823.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/page-66858acbcd1d4bf8.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/agents/{route-2f4705aa66819b86.js → route-2ceea6eabf25b1f2.js} +1 -1
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/{route-2f4705aa66819b86.js → route-2ceea6eabf25b1f2.js} +1 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/config/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/install/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/session/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/copy-skill/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/custom/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/auth/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/backlinks/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/changes/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/export/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/import/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/raw/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/files/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/git/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/graph/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/health/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/init/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/monitoring/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/recent-files/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/restart/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/search/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/skills/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/sync/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/tree-version/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/uninstall/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-check/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-status/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/api/workflows/route-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/changes/page-dd0b00a7b81f74e2.js +1 -0
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-bf5c290fa3ccff09.js +11 -0
- package/_standalone/.next/static/chunks/app/echo/page-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/explore/{page-d3d99308146c2240.js → page-d9f58000bc445360.js} +2 -2
- package/_standalone/.next/static/chunks/app/help/{page-222df603080b5fab.js → page-f8cb806371b3175f.js} +1 -1
- package/_standalone/.next/static/chunks/app/inbox/history/{page-07819cf95cb0805f.js → page-3279585360df132c.js} +1 -1
- package/_standalone/.next/static/chunks/app/layout-6a0169582db11a08.js +164 -0
- package/_standalone/.next/static/chunks/app/loading-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/login/{page-0eeef685052869a6.js → page-18fb00d568cd1f0e.js} +1 -1
- package/_standalone/.next/static/chunks/app/page-6a1f8d21c12b829e.js +1 -0
- package/_standalone/.next/static/chunks/app/setup/{page-99fcfc460fa29733.js → page-821714e7477be46c.js} +1 -1
- package/_standalone/.next/static/chunks/app/trash/page-ed7ba3b0b50223a6.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/{not-found-fc04c2bd4f35bc6f.js → not-found-6e0c75ad26ce8572.js} +1 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-678139779971cfcb.js +12 -0
- package/_standalone/.next/static/chunks/app/wiki/page-194ae9af2d461481.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-2ceea6eabf25b1f2.js +1 -0
- package/_standalone/.next/static/chunks/{webpack-2c19436659aa657b.js → webpack-72e8d9e9073fd1f9.js} +1 -1
- package/_standalone/.next/static/css/9c558c42831fae58.css +1 -0
- package/_standalone/.next/trace +65 -64
- package/_standalone/.next/types/routes.d.ts +2 -1
- package/_standalone/.next/types/validator.ts +9 -0
- package/_standalone/__tests__/api/mcp-install.test.ts +4 -2
- package/_standalone/app/globals.css +2 -1
- package/_standalone/components/AskFab.tsx +11 -5
- package/_standalone/components/AskModal.tsx +1 -1
- package/_standalone/components/FileTree.tsx +83 -1
- package/_standalone/components/GuideCard.tsx +101 -152
- package/_standalone/components/Panel.tsx +6 -1
- package/_standalone/components/RightAskPanel.tsx +2 -2
- package/_standalone/components/agents/AgentsOverviewSection.tsx +13 -11
- package/_standalone/components/agents/CustomAgentModal.tsx +72 -18
- package/_standalone/components/ask/AskContent.tsx +109 -54
- package/_standalone/components/ask/AskHeader.tsx +218 -18
- package/_standalone/components/ask/FileChip.tsx +93 -12
- package/_standalone/components/ask/MessageList.tsx +66 -47
- package/_standalone/components/ask/SessionHistory.tsx +86 -60
- package/_standalone/components/ask/SessionTabBar.tsx +29 -21
- package/_standalone/components/ask/ThinkingBlock.tsx +6 -5
- package/_standalone/components/ask/ToolCallBlock.tsx +10 -9
- package/_standalone/components/changes/ChangesBanner.tsx +1 -1
- package/_standalone/components/settings/SettingsContent.tsx +1 -1
- package/_standalone/components/walkthrough/WalkthroughTooltip.tsx +3 -1
- package/_standalone/components/walkthrough/steps.ts +1 -1
- package/_standalone/data/skills/mindos/SKILL.md +67 -15
- package/_standalone/data/skills/mindos-zh/SKILL.md +67 -11
- package/_standalone/hooks/useAskChat.ts +10 -8
- package/_standalone/hooks/useAskSession.ts +23 -1
- package/_standalone/hooks/useFileUpload.ts +97 -43
- package/_standalone/hooks/useImageUpload.ts +1 -1
- package/_standalone/lib/inbox-upload.ts +86 -0
- package/_standalone/lib/stores/locale-store.ts +20 -6
- package/_standalone/package-lock.json +2 -2
- package/_standalone/package.json +1 -1
- package/_standalone/scripts/extract-pdf.cjs +110 -3
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/api/agents/copy-skill/route.ts +110 -0
- package/app/app/api/agents/custom/detect/route.ts +16 -1
- package/app/app/api/ask/route.ts +7 -1
- package/app/app/api/extract-pdf/route.ts +12 -5
- package/app/app/api/mcp/agents/route.ts +64 -2
- package/app/app/globals.css +2 -1
- package/app/app/layout.tsx +16 -4
- package/app/components/AskFab.tsx +11 -5
- package/app/components/AskModal.tsx +1 -1
- package/app/components/FileTree.tsx +83 -1
- package/app/components/GuideCard.tsx +101 -152
- package/app/components/HomeContent.tsx +123 -574
- package/app/components/Panel.tsx +6 -1
- package/app/components/RightAskPanel.tsx +2 -2
- package/app/components/WikiHomeContent.tsx +151 -3
- package/app/components/agents/AgentDetailContent.tsx +58 -1
- package/app/components/agents/AgentsOverviewSection.tsx +13 -11
- package/app/components/agents/CustomAgentModal.tsx +72 -18
- package/app/components/ask/AskContent.tsx +109 -54
- package/app/components/ask/AskHeader.tsx +218 -18
- package/app/components/ask/FileChip.tsx +93 -12
- package/app/components/ask/MessageList.tsx +66 -47
- package/app/components/ask/SessionHistory.tsx +86 -60
- package/app/components/ask/SessionTabBar.tsx +29 -21
- package/app/components/ask/ThinkingBlock.tsx +6 -5
- package/app/components/ask/ToolCallBlock.tsx +10 -9
- package/app/components/changes/ChangesBanner.tsx +1 -1
- package/app/components/changes/ChangesContentPage.tsx +368 -168
- package/app/components/settings/SettingsContent.tsx +1 -1
- package/app/components/walkthrough/WalkthroughTooltip.tsx +3 -1
- package/app/components/walkthrough/steps.ts +1 -1
- package/app/data/skills/mindos/SKILL.md +67 -15
- package/app/data/skills/mindos-zh/SKILL.md +67 -11
- package/app/hooks/useAskChat.ts +10 -8
- package/app/hooks/useAskSession.ts +23 -1
- package/app/hooks/useFileUpload.ts +97 -43
- package/app/hooks/useImageUpload.ts +1 -1
- package/app/lib/agent/prompt.ts +15 -4
- package/app/lib/custom-agents.ts +109 -1
- package/app/lib/file-ops.ts +58 -0
- package/app/lib/i18n/modules/ai-chat.ts +134 -10
- package/app/lib/i18n/modules/knowledge.ts +2 -0
- package/app/lib/i18n/modules/onboarding.ts +12 -12
- package/app/lib/inbox-upload.ts +86 -0
- package/app/lib/mcp-agents.ts +21 -1
- package/app/lib/stores/LocaleStoreInit.tsx +24 -1
- package/app/lib/stores/locale-store.ts +20 -6
- package/app/lib/types.ts +13 -0
- package/app/package.json +1 -1
- package/app/scripts/extract-pdf.cjs +110 -3
- package/package.json +1 -1
- package/skills/mindos/SKILL.md +67 -15
- package/skills/mindos/references/knowledge-health.md +120 -0
- package/skills/mindos-max/SKILL.md +52 -5
- package/skills/mindos-max-zh/SKILL.md +55 -6
- package/skills/mindos-zh/SKILL.md +67 -11
- package/_standalone/.next/server/chunks/2364.js +0 -2
- package/_standalone/.next/server/chunks/357.js +0 -1
- package/_standalone/.next/static/2ksXveDzEcnCMRIElDkLq/_buildManifest.js +0 -1
- package/_standalone/.next/static/chunks/178-105779afb62d36d9.js +0 -1
- package/_standalone/.next/static/chunks/2218-d54538000574ffef.js +0 -1
- package/_standalone/.next/static/chunks/2549-e63cf57fa927a41d.js +0 -1
- package/_standalone/.next/static/chunks/4237-ffc6e7c15d4007b6.js +0 -1
- package/_standalone/.next/static/chunks/6878-e2c5459e1c608f89.js +0 -1
- package/_standalone/.next/static/chunks/7249-fa98ca10e9a10f39.js +0 -11
- package/_standalone/.next/static/chunks/9274-296ab35f9f09e42e.js +0 -1
- package/_standalone/.next/static/chunks/9286-5b09baa5200318c2.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-7bdeab5af8e4f5f2.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/page-5d1446665ddb3801.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/config/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/install/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/session/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agents/custom/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/auth/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/backlinks/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/changes/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/export/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/import/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/raw/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/files/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/git/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/graph/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/health/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/inbox/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/init/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/monitoring/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/recent-files/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/restart/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/search/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/skills/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/sync/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/tree-version/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/uninstall/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-check/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-status/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/api/workflows/route-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/changes/page-5a72144d1080a699.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-b0103509ce34444b.js +0 -11
- package/_standalone/.next/static/chunks/app/echo/page-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/layout-7e02ddf4144b01f1.js +0 -186
- package/_standalone/.next/static/chunks/app/loading-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/page-6a6a12bd6d6812d0.js +0 -7
- package/_standalone/.next/static/chunks/app/trash/page-54cbd5c98d9de69b.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-ca7bdcbf27f88a46.js +0 -12
- package/_standalone/.next/static/chunks/app/wiki/page-d492256a93f0b8bc.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-2f4705aa66819b86.js +0 -1
- package/_standalone/.next/static/css/fd84c8316ead16eb.css +0 -1
- /package/_standalone/.next/static/{2ksXveDzEcnCMRIElDkLq → K3wZNf5bj_AFYwtqcRXIf}/_ssgManifest.js +0 -0
|
@@ -15,7 +15,6 @@ import MessageList from '@/components/ask/MessageList';
|
|
|
15
15
|
import MentionPopover from '@/components/ask/MentionPopover';
|
|
16
16
|
import SlashCommandPopover from '@/components/ask/SlashCommandPopover';
|
|
17
17
|
import SessionHistory from '@/components/ask/SessionHistory';
|
|
18
|
-
import SessionTabBar from '@/components/ask/SessionTabBar';
|
|
19
18
|
import AskHeader from '@/components/ask/AskHeader';
|
|
20
19
|
import FileChip from '@/components/ask/FileChip';
|
|
21
20
|
import AgentSelectorCapsule from '@/components/ask/AgentSelectorCapsule';
|
|
@@ -65,8 +64,8 @@ interface AskContentProps {
|
|
|
65
64
|
/** ACP agent pre-selected via "Use" button from A2A tab */
|
|
66
65
|
initialAcpAgent?: AcpAgentSelection | null;
|
|
67
66
|
onFirstMessage?: () => void;
|
|
68
|
-
/** 'modal' renders close button + ESC handler; 'panel' renders compact header */
|
|
69
|
-
variant: 'modal' | 'panel';
|
|
67
|
+
/** 'modal' renders close button + ESC handler; 'panel' renders compact header; 'home' renders embedded on homepage */
|
|
68
|
+
variant: 'modal' | 'panel' | 'home';
|
|
70
69
|
/** Required for modal variant — called on close button / ESC / backdrop click */
|
|
71
70
|
onClose?: () => void;
|
|
72
71
|
maximized?: boolean;
|
|
@@ -79,6 +78,7 @@ interface AskContentProps {
|
|
|
79
78
|
|
|
80
79
|
export default function AskContent({ visible, currentFile, initialMessage, initialAcpAgent, onFirstMessage, variant, onClose, maximized, onMaximize, askMode, onModeSwitch }: AskContentProps) {
|
|
81
80
|
const isPanel = variant === 'panel';
|
|
81
|
+
const isHome = variant === 'home';
|
|
82
82
|
|
|
83
83
|
const inputRef = useRef<HTMLTextAreaElement>(null);
|
|
84
84
|
const imageInputRef = useRef<HTMLInputElement>(null);
|
|
@@ -160,12 +160,26 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
160
160
|
return () => window.removeEventListener('mindos:inject-ask-files', handler);
|
|
161
161
|
}, []);
|
|
162
162
|
|
|
163
|
+
// Home suggestion chip click — inject text into input
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
if (!isHome) return;
|
|
166
|
+
const handler = (e: Event) => {
|
|
167
|
+
const text = (e as CustomEvent).detail?.text;
|
|
168
|
+
if (typeof text === 'string') {
|
|
169
|
+
setInput(text);
|
|
170
|
+
setTimeout(() => inputRef.current?.focus(), 50);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
window.addEventListener('mindos:home-suggestion', handler);
|
|
174
|
+
return () => window.removeEventListener('mindos:home-suggestion', handler);
|
|
175
|
+
}, [isHome]);
|
|
176
|
+
|
|
163
177
|
// Focus and init session when becoming visible (edge-triggered for panel, level-triggered for modal)
|
|
164
178
|
const prevVisibleRef = useRef(false);
|
|
165
179
|
const prevFileRef = useRef(currentFile);
|
|
166
180
|
useEffect(() => {
|
|
167
|
-
const justOpened = variant === 'panel'
|
|
168
|
-
? (visible && !prevVisibleRef.current) // panel: edge detection
|
|
181
|
+
const justOpened = variant === 'panel' || variant === 'home'
|
|
182
|
+
? (visible && !prevVisibleRef.current) // panel/home: edge detection
|
|
169
183
|
: visible; // modal: level detection (reset every open)
|
|
170
184
|
|
|
171
185
|
// Detect file change while panel is already open
|
|
@@ -173,14 +187,15 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
173
187
|
|
|
174
188
|
if (justOpened) {
|
|
175
189
|
setTimeout(() => inputRef.current?.focus(), 50);
|
|
190
|
+
// Home variant: also load sessions so user can switch
|
|
176
191
|
void session.initSessions();
|
|
177
192
|
setInput(initialMessage || '');
|
|
178
193
|
chat.firstMessageFired.current = false;
|
|
179
194
|
setAttachedFiles(currentFile ? [currentFile] : []);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
195
|
+
upload.clearAttachments();
|
|
196
|
+
imageUpload.clearImages();
|
|
197
|
+
mention.resetMention();
|
|
198
|
+
slash.resetSlash();
|
|
184
199
|
setSelectedSkill(null);
|
|
185
200
|
setSelectedAcpAgent(initialAcpAgent ?? null);
|
|
186
201
|
setShowHistory(false);
|
|
@@ -191,6 +206,10 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
191
206
|
// Modal: abort streaming on close
|
|
192
207
|
chat.abortRef.current?.abort();
|
|
193
208
|
}
|
|
209
|
+
// Home variant: auto-focus on mount
|
|
210
|
+
if (variant === 'home' && visible && !prevVisibleRef.current) {
|
|
211
|
+
setTimeout(() => inputRef.current?.focus(), 150);
|
|
212
|
+
}
|
|
194
213
|
prevVisibleRef.current = visible;
|
|
195
214
|
prevFileRef.current = currentFile;
|
|
196
215
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -209,9 +228,9 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
209
228
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
210
229
|
}, [visible, session.messages, session.activeSessionId, chat.isLoading]);
|
|
211
230
|
|
|
212
|
-
// Esc to close modal or exit focus mode
|
|
231
|
+
// Esc to close modal or exit focus mode (skip for home variant)
|
|
213
232
|
useEffect(() => {
|
|
214
|
-
if (!visible) return;
|
|
233
|
+
if (!visible || variant === 'home') return;
|
|
215
234
|
const isModal = variant === 'modal';
|
|
216
235
|
const isFocused = variant === 'panel' && maximized;
|
|
217
236
|
if (!isModal && !isFocused) return;
|
|
@@ -376,6 +395,7 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
376
395
|
setSelectedSkill(null);
|
|
377
396
|
setSelectedAcpAgent(null);
|
|
378
397
|
setShowHistory(false);
|
|
398
|
+
chat.firstMessageFired.current = false;
|
|
379
399
|
setTimeout(() => inputRef.current?.focus(), 0);
|
|
380
400
|
}, [currentFile]);
|
|
381
401
|
|
|
@@ -383,6 +403,7 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
383
403
|
// Accept mindos file paths and image drops
|
|
384
404
|
if (e.dataTransfer.types.includes('text/mindos-path') || e.dataTransfer.types.includes('Files')) {
|
|
385
405
|
e.preventDefault();
|
|
406
|
+
e.stopPropagation();
|
|
386
407
|
e.dataTransfer.dropEffect = 'copy';
|
|
387
408
|
setIsDragOver(true);
|
|
388
409
|
}
|
|
@@ -392,6 +413,7 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
392
413
|
|
|
393
414
|
const handleDrop = useCallback(async (e: React.DragEvent) => {
|
|
394
415
|
e.preventDefault();
|
|
416
|
+
e.stopPropagation();
|
|
395
417
|
setIsDragOver(false);
|
|
396
418
|
const filePath = e.dataTransfer.getData('text/mindos-path');
|
|
397
419
|
if (filePath) {
|
|
@@ -402,7 +424,21 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
402
424
|
}
|
|
403
425
|
return;
|
|
404
426
|
}
|
|
405
|
-
|
|
427
|
+
// Try image upload first, then fall back to general file upload
|
|
428
|
+
const files = e.dataTransfer.files;
|
|
429
|
+
if (files.length > 0) {
|
|
430
|
+
const hasImages = Array.from(files).some(f => f.type.startsWith('image/'));
|
|
431
|
+
if (hasImages) {
|
|
432
|
+
await imageUploadRef.current.handleDrop(e);
|
|
433
|
+
}
|
|
434
|
+
// Upload non-image files as attachments
|
|
435
|
+
const nonImageFiles = Array.from(files).filter(f => !f.type.startsWith('image/'));
|
|
436
|
+
if (nonImageFiles.length > 0) {
|
|
437
|
+
const dt = new DataTransfer();
|
|
438
|
+
nonImageFiles.forEach(f => dt.items.add(f));
|
|
439
|
+
await uploadRef.current.pickFiles(dt.files);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
406
442
|
}, []);
|
|
407
443
|
|
|
408
444
|
const handlePaste = useCallback((e: React.ClipboardEvent) => {
|
|
@@ -438,34 +474,31 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
438
474
|
thinking: t.ask.thinking,
|
|
439
475
|
generating: t.ask.generating,
|
|
440
476
|
reconnecting: reconnectAttempt > 0 ? t.ask.reconnecting(reconnectAttempt, reconnectMaxRef.current) : undefined,
|
|
477
|
+
copyMessage: t.ask.copyMessage,
|
|
441
478
|
}), [t, reconnectAttempt]);
|
|
442
479
|
|
|
443
480
|
return (
|
|
444
481
|
<>
|
|
482
|
+
{/* Header — home variant shows session switcher + new/history/fullscreen buttons */}
|
|
445
483
|
<AskHeader
|
|
446
|
-
isPanel={isPanel}
|
|
484
|
+
isPanel={isPanel || isHome}
|
|
447
485
|
showHistory={showHistory}
|
|
448
486
|
onToggleHistory={toggleHistory}
|
|
449
487
|
onReset={handleResetSession}
|
|
450
488
|
isLoading={isLoading}
|
|
451
489
|
maximized={maximized}
|
|
452
|
-
onMaximize={onMaximize}
|
|
453
|
-
askMode={askMode}
|
|
454
|
-
onModeSwitch={onModeSwitch}
|
|
455
|
-
onClose={onClose}
|
|
490
|
+
onMaximize={isHome ? onMaximize : onMaximize}
|
|
491
|
+
askMode={isHome ? undefined : askMode}
|
|
492
|
+
onModeSwitch={isHome ? undefined : onModeSwitch}
|
|
493
|
+
onClose={isHome ? undefined : onClose}
|
|
494
|
+
sessions={session.sessions}
|
|
495
|
+
activeSessionId={session.activeSessionId}
|
|
496
|
+
onLoadSession={handleLoadSession}
|
|
497
|
+
onDeleteSession={session.deleteSession}
|
|
498
|
+
onRenameSession={session.renameSession}
|
|
499
|
+
onTogglePinSession={session.togglePinSession}
|
|
456
500
|
/>
|
|
457
501
|
|
|
458
|
-
{/* Session tabs — panel variant only */}
|
|
459
|
-
{isPanel && session.sessions.length > 0 && (
|
|
460
|
-
<SessionTabBar
|
|
461
|
-
sessions={session.sessions}
|
|
462
|
-
activeSessionId={session.activeSessionId}
|
|
463
|
-
onLoad={handleLoadSession}
|
|
464
|
-
onDelete={session.deleteSession}
|
|
465
|
-
onNew={handleResetSession}
|
|
466
|
-
/>
|
|
467
|
-
)}
|
|
468
|
-
|
|
469
502
|
{showHistory && (
|
|
470
503
|
<SessionHistory
|
|
471
504
|
sessions={session.sessions}
|
|
@@ -473,6 +506,7 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
473
506
|
onLoad={handleLoadSession}
|
|
474
507
|
onDelete={session.deleteSession}
|
|
475
508
|
onRename={session.renameSession}
|
|
509
|
+
onTogglePin={session.togglePinSession}
|
|
476
510
|
onClearAll={session.clearAllSessions}
|
|
477
511
|
labels={{
|
|
478
512
|
title: t.ask.sessionHistory ?? 'Session History',
|
|
@@ -485,16 +519,31 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
485
519
|
)}
|
|
486
520
|
|
|
487
521
|
{/* Messages */}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
522
|
+
{/* Messages — home variant hides empty state (suggestions rendered externally) */}
|
|
523
|
+
{!isHome && (
|
|
524
|
+
<MessageList
|
|
525
|
+
messages={session.messages}
|
|
526
|
+
isLoading={isLoading}
|
|
527
|
+
loadingPhase={loadingPhase}
|
|
528
|
+
emptyPrompt={t.ask.emptyPrompt}
|
|
529
|
+
emptyHint={t.ask.emptyHint}
|
|
530
|
+
suggestions={t.ask.suggestions}
|
|
531
|
+
onSuggestionClick={setInput}
|
|
532
|
+
labels={messageLabels}
|
|
533
|
+
/>
|
|
534
|
+
)}
|
|
535
|
+
{isHome && session.messages.length > 0 && (
|
|
536
|
+
<MessageList
|
|
537
|
+
messages={session.messages}
|
|
538
|
+
isLoading={isLoading}
|
|
539
|
+
loadingPhase={loadingPhase}
|
|
540
|
+
emptyPrompt={t.ask.emptyPrompt}
|
|
541
|
+
emptyHint={t.ask.emptyHint}
|
|
542
|
+
suggestions={[]}
|
|
543
|
+
onSuggestionClick={setInput}
|
|
544
|
+
labels={messageLabels}
|
|
545
|
+
/>
|
|
546
|
+
)}
|
|
498
547
|
|
|
499
548
|
{/* Popovers — flex children so they stay within overflow boundary (absolute positioning would be clipped by RightAskPanel's overflow-hidden) */}
|
|
500
549
|
{mention.mentionQuery !== null && mention.mentionResults.length > 0 && (
|
|
@@ -519,11 +568,11 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
519
568
|
</div>
|
|
520
569
|
)}
|
|
521
570
|
|
|
522
|
-
{/* Composer card — unified input area
|
|
523
|
-
<div className="shrink-0 px-3 pb-2 pt-1">
|
|
571
|
+
{/* Composer card — unified input area */}
|
|
572
|
+
<div className="shrink-0 px-3 pb-2.5 pt-1">
|
|
524
573
|
<div
|
|
525
574
|
className={cn(
|
|
526
|
-
'rounded-xl
|
|
575
|
+
'rounded-xl bg-muted/40 transition-all focus-within:bg-muted/60',
|
|
527
576
|
isDragOver && 'ring-2 ring-[var(--amber)] bg-[var(--amber-dim)]',
|
|
528
577
|
)}
|
|
529
578
|
onDragOver={handleDragOver}
|
|
@@ -538,12 +587,12 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
538
587
|
<FileChip key={f} path={f} variant="kb" onRemove={() => setAttachedFiles(prev => prev.filter(x => x !== f))} />
|
|
539
588
|
))}
|
|
540
589
|
{upload.localAttachments.map((f, idx) => (
|
|
541
|
-
<FileChip key={`up-${f.name}-${idx}`} path={f.name} variant="upload" onRemove={() => upload.removeAttachment(idx)} />
|
|
590
|
+
<FileChip key={`up-${f.name}-${idx}`} path={f.name} variant="upload" status={f.status} error={f.error} truncatedInfo={f.truncatedInfo} onRemove={() => upload.removeAttachment(idx)} />
|
|
542
591
|
))}
|
|
543
592
|
{imageUpload.images.map((img, idx) => (
|
|
544
593
|
<FileChip
|
|
545
594
|
key={`img-${idx}`}
|
|
546
|
-
path={`Image ${idx + 1}`}
|
|
595
|
+
path={img.fileName || `Image ${idx + 1}`}
|
|
547
596
|
variant="image"
|
|
548
597
|
imageData={img.data}
|
|
549
598
|
imageMime={img.mimeType}
|
|
@@ -568,23 +617,23 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
568
617
|
<form
|
|
569
618
|
ref={formRef}
|
|
570
619
|
onSubmit={handleSubmit}
|
|
571
|
-
className="flex items-end gap-1 px-
|
|
620
|
+
className="flex items-end gap-1.5 px-3 py-2"
|
|
572
621
|
>
|
|
573
622
|
{/* + attach button with mini menu */}
|
|
574
623
|
<div className="relative shrink-0">
|
|
575
624
|
<button
|
|
576
625
|
type="button"
|
|
577
626
|
onClick={() => setShowAttachMenu(v => !v)}
|
|
578
|
-
className="p-
|
|
627
|
+
className="p-2 rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/60 transition-colors"
|
|
579
628
|
title={t.hints.attachFile}
|
|
580
629
|
>
|
|
581
630
|
<Plus size={inputIconSize} />
|
|
582
631
|
</button>
|
|
583
632
|
{showAttachMenu && (
|
|
584
|
-
<div className="absolute bottom-full left-0 mb-1 py-1 rounded-
|
|
633
|
+
<div className="absolute bottom-full left-0 mb-1.5 py-1 rounded-xl border border-border/60 bg-card shadow-lg z-50 min-w-[150px] animate-in fade-in-0 slide-in-from-bottom-2 duration-150">
|
|
585
634
|
<button
|
|
586
635
|
type="button"
|
|
587
|
-
className="flex w-full items-center gap-2 px-3 py-
|
|
636
|
+
className="flex w-full items-center gap-2.5 px-3 py-2 text-xs hover:bg-muted transition-colors text-left rounded-lg"
|
|
588
637
|
onClick={() => { setShowAttachMenu(false); upload.uploadInputRef.current?.click(); }}
|
|
589
638
|
>
|
|
590
639
|
<FileText size={12} className="shrink-0 text-muted-foreground" />
|
|
@@ -592,7 +641,7 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
592
641
|
</button>
|
|
593
642
|
<button
|
|
594
643
|
type="button"
|
|
595
|
-
className="flex w-full items-center gap-2 px-3 py-
|
|
644
|
+
className="flex w-full items-center gap-2.5 px-3 py-2 text-xs hover:bg-muted transition-colors text-left rounded-lg"
|
|
596
645
|
onClick={() => { setShowAttachMenu(false); imageInputRef.current?.click(); }}
|
|
597
646
|
>
|
|
598
647
|
<ImageIcon size={12} className="shrink-0 text-muted-foreground" />
|
|
@@ -637,23 +686,24 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
637
686
|
onPaste={handlePaste}
|
|
638
687
|
placeholder={t.ask.placeholder}
|
|
639
688
|
rows={1}
|
|
640
|
-
className="min-w-0 flex-1 resize-none overflow-y-hidden bg-transparent py-
|
|
689
|
+
className="min-w-0 flex-1 resize-none overflow-y-hidden bg-transparent py-2 text-sm leading-relaxed text-foreground placeholder:text-muted-foreground/50 outline-none focus-visible:ring-0"
|
|
641
690
|
/>
|
|
642
691
|
|
|
643
692
|
{isLoading ? (
|
|
644
|
-
<button type="button" onClick={handleStop} className="p-
|
|
693
|
+
<button type="button" onClick={handleStop} className="p-2 rounded-xl transition-colors shrink-0 text-foreground bg-muted hover:bg-muted/80" title={loadingPhase === 'reconnecting' ? t.ask.cancelReconnect : t.ask.stopTitle}>
|
|
645
694
|
{loadingPhase === 'reconnecting' ? <X size={inputIconSize} /> : <StopCircle size={inputIconSize} />}
|
|
646
695
|
</button>
|
|
647
696
|
) : (
|
|
648
|
-
<button type="submit" disabled={!input.trim() && imageUpload.images.length === 0} className="p-
|
|
697
|
+
<button type="submit" disabled={!input.trim() && imageUpload.images.length === 0} className="p-2 rounded-xl disabled:opacity-20 disabled:scale-95 disabled:cursor-not-allowed transition-all duration-150 shrink-0 bg-[var(--amber)] text-[var(--amber-foreground)] shadow-sm shadow-[var(--amber)]/15 hover:shadow-md hover:shadow-[var(--amber)]/20 active:scale-95">
|
|
649
698
|
<Send size={14} />
|
|
650
699
|
</button>
|
|
651
700
|
)}
|
|
652
701
|
</form>
|
|
653
702
|
|
|
654
|
-
{/* Mode + Agent + Provider selector row
|
|
655
|
-
<div className="flex items-center
|
|
656
|
-
<
|
|
703
|
+
{/* Mode + Agent + Provider selector row + keyboard hint */}
|
|
704
|
+
<div className="flex items-center justify-between px-3 pb-2 pt-1.5 border-t border-border/10">
|
|
705
|
+
<div className="flex items-center gap-2">
|
|
706
|
+
<ModeCapsule mode={chatMode} onChange={setChatMode} disabled={isLoading} />
|
|
657
707
|
{mounted && acpDetection.installedAgents.length > 0 && (
|
|
658
708
|
<AgentSelectorCapsule
|
|
659
709
|
selectedAgent={selectedAcpAgent}
|
|
@@ -669,6 +719,11 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
669
719
|
disabled={isLoading}
|
|
670
720
|
/>
|
|
671
721
|
)}
|
|
722
|
+
</div>
|
|
723
|
+
{/* Keyboard hint */}
|
|
724
|
+
<span className="hidden md:inline text-2xs text-muted-foreground/40 select-none">
|
|
725
|
+
<kbd className="font-mono">Enter</kbd> {t.ask.send} · <kbd className="font-mono">Shift+Enter</kbd> {t.ask.newlineHint}
|
|
726
|
+
</span>
|
|
672
727
|
</div>
|
|
673
728
|
</div>
|
|
674
729
|
</div>
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { memo } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import { memo, useState, useRef, useEffect, useCallback } from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
3
|
+
import { Sparkles, SquarePen, History, X, Maximize2, Minimize2, PanelRight, AppWindow, ChevronDown, Check, Trash2, Pencil, Pin, PinOff } from 'lucide-react';
|
|
3
4
|
import { useLocale } from '@/lib/stores/locale-store';
|
|
5
|
+
import type { ChatSession } from '@/lib/types';
|
|
6
|
+
import { sessionTitle } from '@/hooks/useAskSession';
|
|
4
7
|
|
|
5
8
|
interface AskHeaderProps {
|
|
6
9
|
isPanel: boolean;
|
|
@@ -13,49 +16,246 @@ interface AskHeaderProps {
|
|
|
13
16
|
askMode?: 'panel' | 'popup';
|
|
14
17
|
onModeSwitch?: () => void;
|
|
15
18
|
onClose?: () => void;
|
|
19
|
+
hideTitle?: boolean;
|
|
20
|
+
/** Session switching — inline in header when >=2 sessions */
|
|
21
|
+
sessions?: ChatSession[];
|
|
22
|
+
activeSessionId?: string | null;
|
|
23
|
+
onLoadSession?: (id: string) => void;
|
|
24
|
+
onDeleteSession?: (id: string) => void;
|
|
25
|
+
onRenameSession?: (id: string, name: string) => void;
|
|
26
|
+
onTogglePinSession?: (id: string) => void;
|
|
16
27
|
}
|
|
17
28
|
|
|
18
29
|
export default memo(function AskHeader({
|
|
19
30
|
isPanel, showHistory, onToggleHistory, onReset, isLoading,
|
|
20
|
-
maximized, onMaximize, askMode, onModeSwitch, onClose,
|
|
31
|
+
maximized, onMaximize, askMode, onModeSwitch, onClose, hideTitle,
|
|
32
|
+
sessions, activeSessionId, onLoadSession, onDeleteSession, onRenameSession, onTogglePinSession,
|
|
21
33
|
}: AskHeaderProps) {
|
|
22
34
|
const { t } = useLocale();
|
|
23
|
-
const iconSize =
|
|
35
|
+
const iconSize = 14;
|
|
36
|
+
const hasMultipleSessions = sessions && sessions.length >= 1;
|
|
37
|
+
const activeSession = sessions?.find(s => s.id === activeSessionId);
|
|
38
|
+
const activeTitle = activeSession ? sessionTitle(activeSession) : null;
|
|
39
|
+
|
|
40
|
+
// Session switcher dropdown state
|
|
41
|
+
const [switcherOpen, setSwitcherOpen] = useState(false);
|
|
42
|
+
const switcherRef = useRef<HTMLButtonElement>(null);
|
|
43
|
+
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
44
|
+
|
|
45
|
+
// Inline rename state
|
|
46
|
+
const [renamingId, setRenamingId] = useState<string | null>(null);
|
|
47
|
+
const [renameValue, setRenameValue] = useState('');
|
|
48
|
+
const renameInputRef = useRef<HTMLInputElement>(null);
|
|
49
|
+
|
|
50
|
+
// Close on outside click
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!switcherOpen) return;
|
|
53
|
+
const handler = (e: MouseEvent) => {
|
|
54
|
+
const target = e.target as Node;
|
|
55
|
+
if (
|
|
56
|
+
switcherRef.current && !switcherRef.current.contains(target) &&
|
|
57
|
+
dropdownRef.current && !dropdownRef.current.contains(target)
|
|
58
|
+
) {
|
|
59
|
+
setSwitcherOpen(false);
|
|
60
|
+
setRenamingId(null);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
document.addEventListener('mousedown', handler);
|
|
64
|
+
return () => document.removeEventListener('mousedown', handler);
|
|
65
|
+
}, [switcherOpen]);
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (!switcherOpen) return;
|
|
69
|
+
const handler = (e: KeyboardEvent) => {
|
|
70
|
+
if (e.key === 'Escape') {
|
|
71
|
+
if (renamingId) { setRenamingId(null); } else { setSwitcherOpen(false); }
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
document.addEventListener('keydown', handler);
|
|
75
|
+
return () => document.removeEventListener('keydown', handler);
|
|
76
|
+
}, [switcherOpen, renamingId]);
|
|
77
|
+
|
|
78
|
+
// Focus rename input when it appears
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (renamingId) setTimeout(() => renameInputRef.current?.focus(), 0);
|
|
81
|
+
}, [renamingId]);
|
|
82
|
+
|
|
83
|
+
const handleSelectSession = useCallback((id: string) => {
|
|
84
|
+
onLoadSession?.(id);
|
|
85
|
+
setSwitcherOpen(false);
|
|
86
|
+
}, [onLoadSession]);
|
|
87
|
+
|
|
88
|
+
const handleStartRename = useCallback((id: string, currentTitle: string) => {
|
|
89
|
+
setRenamingId(id);
|
|
90
|
+
setRenameValue(currentTitle === '(empty session)' ? '' : currentTitle);
|
|
91
|
+
}, []);
|
|
92
|
+
|
|
93
|
+
const handleCommitRename = useCallback(() => {
|
|
94
|
+
if (renamingId && onRenameSession && renameValue.trim()) {
|
|
95
|
+
onRenameSession(renamingId, renameValue.trim());
|
|
96
|
+
}
|
|
97
|
+
setRenamingId(null);
|
|
98
|
+
}, [renamingId, renameValue, onRenameSession]);
|
|
99
|
+
|
|
100
|
+
// Position dropdown below trigger
|
|
101
|
+
const [dropPos, setDropPos] = useState<{ top: number; left: number; width: number } | null>(null);
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (!switcherOpen || !switcherRef.current) return;
|
|
104
|
+
const rect = switcherRef.current.getBoundingClientRect();
|
|
105
|
+
setDropPos({ top: rect.bottom + 4, left: rect.left, width: Math.max(rect.width, 240) });
|
|
106
|
+
}, [switcherOpen]);
|
|
107
|
+
|
|
108
|
+
const switcherDropdown = switcherOpen && dropPos && sessions ? createPortal(
|
|
109
|
+
<div
|
|
110
|
+
ref={dropdownRef}
|
|
111
|
+
className="fixed z-50 rounded-xl border border-border/50 bg-card shadow-lg py-1 animate-in fade-in-0 slide-in-from-top-1 duration-100"
|
|
112
|
+
style={{ top: dropPos.top, left: dropPos.left, minWidth: dropPos.width, maxWidth: 320 }}
|
|
113
|
+
role="listbox"
|
|
114
|
+
>
|
|
115
|
+
{sessions.map((s) => {
|
|
116
|
+
const isActive = s.id === activeSessionId;
|
|
117
|
+
const title = sessionTitle(s);
|
|
118
|
+
const displayTitle = title === '(empty session)' ? (t.hints?.newChat ?? 'New chat') : title;
|
|
119
|
+
|
|
120
|
+
if (renamingId === s.id) {
|
|
121
|
+
return (
|
|
122
|
+
<div key={s.id} className="flex items-center gap-1 px-2 py-1.5">
|
|
123
|
+
<input
|
|
124
|
+
ref={renameInputRef}
|
|
125
|
+
type="text"
|
|
126
|
+
value={renameValue}
|
|
127
|
+
onChange={(e) => setRenameValue(e.target.value)}
|
|
128
|
+
onKeyDown={(e) => {
|
|
129
|
+
if (e.key === 'Enter') handleCommitRename();
|
|
130
|
+
if (e.key === 'Escape') setRenamingId(null);
|
|
131
|
+
}}
|
|
132
|
+
onBlur={handleCommitRename}
|
|
133
|
+
className="flex-1 min-w-0 px-2 py-1 text-xs rounded-md border border-border bg-background text-foreground outline-none focus:border-[var(--amber)]/50"
|
|
134
|
+
placeholder="Session name..."
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<div key={s.id} className="group/item flex items-center">
|
|
142
|
+
<button
|
|
143
|
+
type="button"
|
|
144
|
+
role="option"
|
|
145
|
+
aria-selected={isActive}
|
|
146
|
+
onClick={() => handleSelectSession(s.id)}
|
|
147
|
+
className={`flex-1 min-w-0 flex items-center gap-2 px-3 py-2 text-xs text-left transition-colors ${
|
|
148
|
+
isActive ? 'text-foreground font-medium' : 'text-muted-foreground hover:text-foreground hover:bg-muted/50'
|
|
149
|
+
}`}
|
|
150
|
+
>
|
|
151
|
+
{s.pinned && <Pin size={10} className="shrink-0 text-[var(--amber)]/60 -rotate-45" />}
|
|
152
|
+
{isActive && !s.pinned && <Check size={11} className="shrink-0 text-[var(--amber)]" />}
|
|
153
|
+
<span className="truncate">{displayTitle}</span>
|
|
154
|
+
</button>
|
|
155
|
+
<div className="shrink-0 flex items-center gap-0.5 mr-1 opacity-0 group-hover/item:opacity-100 transition-opacity">
|
|
156
|
+
{onTogglePinSession && (
|
|
157
|
+
<button
|
|
158
|
+
type="button"
|
|
159
|
+
onClick={(e) => { e.stopPropagation(); onTogglePinSession(s.id); }}
|
|
160
|
+
className={`p-1.5 rounded-md transition-colors ${s.pinned ? 'text-[var(--amber)] hover:text-muted-foreground hover:bg-muted/60' : 'text-muted-foreground/40 hover:text-[var(--amber)] hover:bg-[var(--amber)]/5'}`}
|
|
161
|
+
aria-label={s.pinned ? 'Unpin' : 'Pin'}
|
|
162
|
+
>
|
|
163
|
+
{s.pinned ? <PinOff size={10} /> : <Pin size={10} />}
|
|
164
|
+
</button>
|
|
165
|
+
)}
|
|
166
|
+
{onRenameSession && (
|
|
167
|
+
<button
|
|
168
|
+
type="button"
|
|
169
|
+
onClick={(e) => { e.stopPropagation(); handleStartRename(s.id, title); }}
|
|
170
|
+
className="p-1.5 rounded-md text-muted-foreground/40 hover:text-foreground hover:bg-muted/60"
|
|
171
|
+
aria-label={`Rename: ${displayTitle}`}
|
|
172
|
+
>
|
|
173
|
+
<Pencil size={10} />
|
|
174
|
+
</button>
|
|
175
|
+
)}
|
|
176
|
+
{sessions.length > 1 && onDeleteSession && (
|
|
177
|
+
<button
|
|
178
|
+
type="button"
|
|
179
|
+
onClick={(e) => { e.stopPropagation(); onDeleteSession(s.id); }}
|
|
180
|
+
className="p-1.5 rounded-md text-muted-foreground/40 hover:text-error hover:bg-error/5"
|
|
181
|
+
aria-label={`Delete: ${displayTitle}`}
|
|
182
|
+
>
|
|
183
|
+
<Trash2 size={10} />
|
|
184
|
+
</button>
|
|
185
|
+
)}
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
);
|
|
189
|
+
})}
|
|
190
|
+
</div>,
|
|
191
|
+
document.body,
|
|
192
|
+
) : null;
|
|
24
193
|
|
|
25
194
|
return (
|
|
26
|
-
<div className="flex items-center justify-between px-4 py-
|
|
195
|
+
<div className="flex items-center justify-between px-4 py-2.5 shrink-0">
|
|
27
196
|
{!isPanel && (
|
|
28
197
|
<div className="absolute top-2 left-1/2 -translate-x-1/2 w-8 h-1 rounded-full bg-muted-foreground/20 md:hidden" />
|
|
29
198
|
)}
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
199
|
+
{!hideTitle && (
|
|
200
|
+
<div className="flex items-center gap-2 min-w-0">
|
|
201
|
+
<div className="w-6 h-6 rounded-lg bg-[var(--amber)]/10 flex items-center justify-center shrink-0">
|
|
202
|
+
<Sparkles size={13} className="text-[var(--amber)]" />
|
|
203
|
+
</div>
|
|
204
|
+
{hasMultipleSessions && activeTitle ? (
|
|
205
|
+
<button
|
|
206
|
+
ref={switcherRef}
|
|
207
|
+
type="button"
|
|
208
|
+
onClick={() => {
|
|
209
|
+
if (sessions && sessions.length >= 2) {
|
|
210
|
+
setSwitcherOpen(v => !v);
|
|
211
|
+
} else {
|
|
212
|
+
onToggleHistory();
|
|
213
|
+
}
|
|
214
|
+
}}
|
|
215
|
+
className="flex items-center gap-1 min-w-0 text-sm font-medium text-[var(--amber)] hover:text-[var(--amber)]/80 transition-colors"
|
|
216
|
+
aria-expanded={switcherOpen}
|
|
217
|
+
aria-haspopup="listbox"
|
|
218
|
+
>
|
|
219
|
+
<span className="truncate max-w-[180px]">{activeTitle === '(empty session)' ? (t.hints?.newChat ?? 'New chat') : activeTitle}</span>
|
|
220
|
+
<ChevronDown size={12} className={`shrink-0 text-muted-foreground transition-transform duration-150 ${switcherOpen ? 'rotate-180' : ''}`} />
|
|
221
|
+
</button>
|
|
222
|
+
) : activeTitle ? (
|
|
223
|
+
<span className="text-sm font-medium text-muted-foreground/60 truncate max-w-[180px]">
|
|
224
|
+
{activeTitle === '(empty session)' ? (t.hints?.newChat ?? 'New chat') : activeTitle}
|
|
225
|
+
</span>
|
|
226
|
+
) : (
|
|
227
|
+
/* Placeholder while sessions load — avoids flash of "MindOS Agent" text */
|
|
228
|
+
<span className="text-sm font-medium text-muted-foreground/40">
|
|
229
|
+
{t.hints?.newChat ?? 'New chat'}
|
|
230
|
+
</span>
|
|
231
|
+
)}
|
|
232
|
+
</div>
|
|
233
|
+
)}
|
|
234
|
+
{hideTitle && <div />}
|
|
36
235
|
<div className="flex items-center gap-1 shrink-0">
|
|
37
|
-
<button type="button" onClick={(e) => { e.stopPropagation(); onToggleHistory(); }} aria-pressed={showHistory} className={`p-2 rounded transition-colors ${showHistory ? 'bg-
|
|
236
|
+
<button type="button" onClick={(e) => { e.stopPropagation(); onToggleHistory(); }} aria-pressed={showHistory} className={`p-2 rounded-lg transition-colors ${showHistory ? 'bg-[var(--amber)]/10 text-[var(--amber)]' : 'text-muted-foreground hover:text-foreground hover:bg-muted'}`} title={t.hints.sessionHistory}>
|
|
38
237
|
<History size={iconSize} />
|
|
39
238
|
</button>
|
|
40
|
-
<button type="button" onClick={(e) => { e.stopPropagation(); onReset(); }} disabled={isLoading} className="p-2 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-40" title={t.hints.newSession}>
|
|
239
|
+
<button type="button" onClick={(e) => { e.stopPropagation(); onReset(); }} disabled={isLoading} className="p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-40" title={t.hints.newSession}>
|
|
41
240
|
<SquarePen size={iconSize} />
|
|
42
241
|
</button>
|
|
43
|
-
{
|
|
44
|
-
<button type="button" onClick={(e) => { e.stopPropagation(); onMaximize(); }} className="p-2 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={maximized ? t.hints.restorePanel : t.hints.maximizePanel}>
|
|
242
|
+
{onMaximize && (
|
|
243
|
+
<button type="button" onClick={(e) => { e.stopPropagation(); onMaximize(); }} className="p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={maximized ? t.hints.restorePanel : t.hints.maximizePanel}>
|
|
45
244
|
{maximized ? <Minimize2 size={iconSize} /> : <Maximize2 size={iconSize} />}
|
|
46
245
|
</button>
|
|
47
246
|
)}
|
|
48
247
|
{onModeSwitch && (
|
|
49
|
-
<button type="button" onClick={(e) => { e.stopPropagation(); onModeSwitch(); }} className="p-2 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={askMode === 'popup' ? t.hints.dockToSide : t.hints.openAsPopup}>
|
|
248
|
+
<button type="button" onClick={(e) => { e.stopPropagation(); onModeSwitch(); }} className="p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={askMode === 'popup' ? t.hints.dockToSide : t.hints.openAsPopup}>
|
|
50
249
|
{askMode === 'popup' ? <PanelRight size={iconSize} /> : <AppWindow size={iconSize} />}
|
|
51
250
|
</button>
|
|
52
251
|
)}
|
|
53
252
|
{onClose && (
|
|
54
|
-
<button type="button" onClick={(e) => { e.stopPropagation(); onClose(); }} className="p-2 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={t.hints.closePanel} aria-label="Close">
|
|
55
|
-
<X size={
|
|
253
|
+
<button type="button" onClick={(e) => { e.stopPropagation(); onClose(); }} className="p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground transition-colors" title={t.hints.closePanel} aria-label="Close">
|
|
254
|
+
<X size={iconSize} />
|
|
56
255
|
</button>
|
|
57
256
|
)}
|
|
58
257
|
</div>
|
|
258
|
+
{typeof document !== 'undefined' && switcherDropdown}
|
|
59
259
|
</div>
|
|
60
260
|
);
|
|
61
261
|
});
|