@geminilight/mindos 0.6.39 → 0.6.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -15
- package/README_zh.md +31 -15
- package/_standalone/.mindos-build-version +1 -1
- package/_standalone/.next/BUILD_ID +1 -1
- package/_standalone/.next/app-path-routes-manifest.json +19 -18
- 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 +68 -2
- 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 +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.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route.js.nft.json +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.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route.js.nft.json +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.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route.js.nft.json +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.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route.js.nft.json +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 +137 -99
- 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 +3 -3
- 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 +2 -19
- 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 -18
- 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 -0
- package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -0
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -0
- 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.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/status/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.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route.js.nft.json +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.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route.js.nft.json +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.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/route.js +1 -1
- package/_standalone/.next/server/app/api/setup/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/skills/route.js +2 -2
- package/_standalone/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/sync/route.js +1 -1
- package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route.js +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.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 +2 -2
- 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 +6 -6
- 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 +3 -3
- 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 +3 -3
- package/_standalone/.next/server/app/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/setup/page.js +2 -2
- package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/trash/page.js +3 -3
- package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +4 -4
- 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 +19 -18
- package/_standalone/.next/server/chunks/1550.js +1 -1
- package/_standalone/.next/server/chunks/1750.js +1 -0
- package/_standalone/.next/server/chunks/{9414.js → 2190.js} +1 -1
- package/_standalone/.next/server/chunks/2536.js +52 -0
- package/_standalone/.next/server/chunks/5648.js +2 -0
- package/_standalone/.next/server/chunks/6539.js +1 -1
- package/_standalone/.next/server/chunks/8388.js +15 -0
- package/_standalone/.next/server/chunks/953.js +42 -2
- package/_standalone/.next/server/chunks/9539.js +219 -0
- package/_standalone/.next/server/functions-config-manifest.json +2 -1
- 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/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/Ij3PFh-a0zi5K_ANoSAW0/_buildManifest.js +1 -0
- package/_standalone/.next/static/chunks/1053-b70535785cc5aaee.js +29 -0
- package/_standalone/.next/static/chunks/1239.10a0710c2772ab34.js +1 -0
- package/_standalone/.next/static/chunks/{1814.e2da5460ded71d71.js → 1814.2ee1d03297c0bccd.js} +1 -1
- package/_standalone/.next/static/chunks/{1384-55276d40a9da4e88.js → 1880-c2a9e76201841c86.js} +2 -2
- package/_standalone/.next/static/chunks/{1a258343-030e4d6735874dd4.js → 1a258343-9803591e4aaee1f6.js} +1 -1
- package/_standalone/.next/static/chunks/2631.dc56e83472bde281.js +1 -0
- package/_standalone/.next/static/chunks/2872.045858d00bd8307f.js +8 -0
- package/_standalone/.next/static/chunks/2968.f10ccee9e7e2324d.js +2 -0
- package/_standalone/.next/static/chunks/3160-83a7e0b94414b3ac.js +1 -0
- package/_standalone/.next/static/chunks/3637.0541ac2d0ea7de1f.js +1 -0
- package/_standalone/.next/static/chunks/4033.6666700547b20141.js +1 -0
- package/_standalone/.next/static/chunks/4563-b2a2ce80aff845af.js +6 -0
- package/_standalone/.next/static/chunks/516.24ee058b1d4b1fed.js +8 -0
- package/_standalone/.next/static/chunks/5627.c4337d7289acb31f.js +1 -0
- package/_standalone/.next/static/chunks/5956.b445072b35915129.js +1 -0
- package/_standalone/.next/static/chunks/6357-c645842834c0d4cd.js +1 -0
- package/_standalone/.next/static/chunks/6826.7b7d94dd0fd83812.js +1 -0
- package/_standalone/.next/static/chunks/{8409-de5726a4a278d28f.js → 6926-4af497b83952fa87.js} +1 -1
- package/_standalone/.next/static/chunks/6981-3d7dcac2d12a5670.js +1 -0
- package/_standalone/.next/static/chunks/7144-5febf62f1a79fe64.js +1 -0
- package/_standalone/.next/static/chunks/7266-bb7be1128eccd48e.js +13 -0
- package/_standalone/.next/static/chunks/7753.63831cfc54a55fbb.js +1 -0
- package/_standalone/.next/static/chunks/862.9f526e964489e2e5.js +1 -0
- package/_standalone/.next/static/chunks/9300.118b8c840634383f.js +28 -0
- package/_standalone/.next/static/chunks/95247769.3b5caae1c1a76ce1.js +4 -0
- package/_standalone/.next/static/chunks/9602-423291fdb36396d1.js +1 -0
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/_global-error/page-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-773071a99c4daac2.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/page-6102a884b2cb3cfe.js +5 -0
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/config/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/install/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/session/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/auth/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/backlinks/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/changes/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/export/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/import/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/files/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/git/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/graph/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/health/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/init/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/monitoring/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/recent-files/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/restart/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/search/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/skills/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/sync/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/tree-version/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/uninstall/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-check/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-status/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/workflows/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/changes/page-350992cf5091bc5b.js +1 -0
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-addf014fcf23fad5.js +11 -0
- package/_standalone/.next/static/chunks/app/echo/page-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/explore/page-5eb2835e9e3ab4bb.js +4 -0
- package/_standalone/.next/static/chunks/app/help/page-2325d25b6846ca07.js +1 -0
- package/_standalone/.next/static/chunks/app/layout-42cdbce19f404567.js +186 -0
- package/_standalone/.next/static/chunks/app/login/page-24236460fa7c11d0.js +1 -0
- package/_standalone/.next/static/chunks/app/page-8c9643b649e01735.js +7 -0
- package/_standalone/.next/static/chunks/app/setup/page-d158b8cb533feb1e.js +1 -0
- package/_standalone/.next/static/chunks/app/trash/page-e9ab74ffeb96af41.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/not-found-61474670d6bb6116.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-764a69a1c8bd4eef.js +12 -0
- package/_standalone/.next/static/chunks/e71f6c19-4df85185bf989b49.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/webpack-7b276daaa930d480.js +1 -0
- package/_standalone/.next/static/css/bc9179074eaf65ae.css +1 -0
- package/_standalone/.next/trace +63 -53
- package/_standalone/.next/types/routes.d.ts +2 -1
- package/_standalone/.next/types/validator.ts +9 -0
- package/_standalone/__tests__/agent/chat-mode.test.ts +103 -0
- package/_standalone/__tests__/agents/agents-content-dashboard.test.tsx +4 -3
- package/_standalone/__tests__/api/bootstrap.test.ts +0 -2
- package/_standalone/__tests__/api/file.test.ts +22 -1
- package/_standalone/__tests__/api/install-skill.test.ts +2 -2
- package/_standalone/__tests__/api/mcp-install.test.ts +32 -10
- package/_standalone/__tests__/api/setup.test.ts +2 -2
- package/_standalone/__tests__/api/test-key.test.ts +73 -147
- package/_standalone/__tests__/ask/ask-content-input-during-run.test.tsx +1 -1
- package/_standalone/__tests__/ask/mode-capsule.test.ts +95 -0
- package/_standalone/__tests__/cli/agent-routing.test.ts +232 -0
- package/_standalone/__tests__/cli/file-subcommands.test.ts +379 -0
- package/_standalone/__tests__/core/inbox.test.ts +250 -0
- package/_standalone/__tests__/core/skill-install-logic.test.ts +3 -3
- package/_standalone/__tests__/core/sync-status.test.ts +1 -1
- package/_standalone/__tests__/core/tools.test.ts +8 -6
- package/_standalone/__tests__/lib/echo-pages-visual-i18n.test.ts +2 -2
- package/_standalone/__tests__/lib/i18n-new-keys.test.ts +2 -2
- package/_standalone/__tests__/panels/agents-panel-hub.test.tsx +2 -2
- package/_standalone/__tests__/settings/activity-bar-update-badge.test.tsx +1 -1
- package/_standalone/__tests__/settings/settings-update-badge.test.tsx +1 -1
- package/_standalone/__tests__/settings/update-tab-availability-sync.test.tsx +1 -1
- package/_standalone/__tests__/settings/update-tab-browser.test.tsx +1 -1
- package/_standalone/__tests__/settings/update-tab-desktop.test.tsx +1 -1
- package/_standalone/__tests__/setup.ts +3 -5
- package/_standalone/app/globals.css +11 -1
- package/_standalone/components/ActivityBar.tsx +26 -10
- package/_standalone/components/AskFab.tsx +1 -1
- package/_standalone/components/AskModal.tsx +1 -1
- package/_standalone/components/Backlinks.tsx +1 -1
- package/_standalone/components/CreateSpaceModal.tsx +7 -55
- package/_standalone/components/EchoSpotlight.tsx +1 -1
- package/_standalone/components/ExportModal.tsx +1 -1
- package/_standalone/components/FileTree.tsx +66 -80
- package/_standalone/components/FindInPage.tsx +1 -1
- package/_standalone/components/GuideCard.tsx +1 -1
- package/_standalone/components/ImportModal.tsx +1 -1
- package/_standalone/components/KeyboardShortcuts.tsx +1 -1
- package/_standalone/components/MarkdownView.tsx +41 -16
- package/_standalone/components/OnboardingView.tsx +1 -1
- package/_standalone/components/OrganizeToast.tsx +1 -1
- package/_standalone/components/Panel.tsx +82 -4
- package/_standalone/components/QuickSuggestion.tsx +1 -1
- package/_standalone/components/RightAgentDetailPanel.tsx +2 -2
- package/_standalone/components/RightAskPanel.tsx +88 -22
- package/_standalone/components/SearchModal.tsx +1 -1
- package/_standalone/components/Sidebar.tsx +4 -4
- package/_standalone/components/SidebarLayout.tsx +52 -16
- package/_standalone/components/SpaceInitToast.tsx +1 -1
- package/_standalone/components/SyncStatusBar.tsx +2 -2
- package/_standalone/components/SystemPulse.tsx +12 -6
- package/_standalone/components/TableOfContents.tsx +86 -39
- package/_standalone/components/agents/AgentActivitySection.tsx +225 -0
- package/_standalone/components/agents/AgentsMcpSection.tsx +10 -16
- package/_standalone/components/agents/AgentsOverviewSection.tsx +28 -27
- package/_standalone/components/agents/AgentsPanelA2aTab.tsx +1 -1
- package/_standalone/components/agents/AgentsPanelSessionsTab.tsx +6 -1
- package/_standalone/components/agents/AgentsSkillsSection.tsx +1 -1
- package/_standalone/components/agents/DiscoverAgentModal.tsx +1 -1
- package/_standalone/components/agents/RecentActivityFeed.tsx +49 -88
- package/_standalone/components/agents/agent-activity-shared.tsx +110 -0
- package/_standalone/components/ask/AgentSelectorCapsule.tsx +1 -1
- package/_standalone/components/ask/AskContent.tsx +332 -486
- package/_standalone/components/ask/AskHeader.tsx +61 -0
- package/_standalone/components/ask/FileChip.tsx +9 -5
- package/_standalone/components/ask/MessageList.tsx +88 -21
- package/_standalone/components/ask/ModeCapsule.tsx +180 -0
- package/_standalone/components/ask/ProviderModelCapsule.tsx +284 -0
- package/_standalone/components/ask/SessionHistory.tsx +63 -10
- package/_standalone/components/ask/SessionTabBar.tsx +1 -1
- package/_standalone/components/ask/ThinkingBlock.tsx +1 -1
- package/_standalone/components/ask/ToolCallBlock.tsx +28 -24
- package/_standalone/components/changes/ChangesBanner.tsx +1 -1
- package/_standalone/components/echo/EchoInsightCollapsible.tsx +1 -1
- package/_standalone/components/echo/EchoSegmentNav.tsx +1 -1
- package/_standalone/components/home/InboxSection.tsx +268 -0
- package/_standalone/components/panels/AgentsPanel.tsx +3 -2
- package/_standalone/components/panels/AgentsPanelHubNav.tsx +2 -6
- package/_standalone/components/panels/DiscoverPanel.tsx +1 -1
- package/_standalone/components/panels/EchoPanel.tsx +1 -1
- package/_standalone/components/panels/EchoSidebarStats.tsx +1 -1
- package/_standalone/components/panels/ImportHistoryPanel.tsx +1 -1
- package/_standalone/components/panels/PanelHeader.tsx +1 -1
- package/_standalone/components/panels/PluginsPanel.tsx +1 -1
- package/_standalone/components/panels/SearchPanel.tsx +5 -2
- package/_standalone/components/panels/SyncPopover.tsx +1 -1
- package/_standalone/components/panels/WorkflowsPanel.tsx +1 -1
- package/_standalone/components/renderers/agent-inspector/AgentInspectorRenderer.tsx +18 -0
- package/_standalone/components/renderers/todo/TodoRenderer.tsx +489 -75
- package/_standalone/components/settings/AiTab.tsx +198 -127
- package/_standalone/components/settings/AppearanceTab.tsx +48 -50
- package/_standalone/components/settings/KnowledgeTab.tsx +92 -27
- package/_standalone/components/settings/McpAgentInstall.tsx +95 -28
- package/_standalone/components/settings/McpSkillsSection.tsx +2 -2
- package/_standalone/components/settings/McpTab.tsx +498 -216
- package/_standalone/components/settings/PluginsTab.tsx +1 -1
- package/_standalone/components/settings/SettingsContent.tsx +17 -8
- package/_standalone/components/settings/SyncTab.tsx +615 -230
- package/_standalone/components/settings/UninstallTab.tsx +1 -1
- package/_standalone/components/settings/UpdateTab.tsx +2 -2
- package/_standalone/components/settings/types.ts +7 -5
- package/_standalone/components/setup/StepAI.tsx +70 -49
- package/_standalone/components/setup/StepAgents.tsx +113 -47
- package/_standalone/components/setup/StepDots.tsx +1 -1
- package/_standalone/components/setup/StepReview.tsx +186 -31
- package/_standalone/components/setup/types.ts +17 -8
- package/_standalone/components/shared/ProviderSelect.tsx +134 -0
- package/_standalone/components/walkthrough/WalkthroughOverlay.tsx +2 -2
- package/_standalone/components/walkthrough/WalkthroughTooltip.tsx +2 -2
- package/_standalone/components/walkthrough/index.ts +1 -1
- package/_standalone/data/skills/mindos/SKILL.md +93 -93
- package/_standalone/data/skills/mindos/references/write-supplement.md +119 -0
- package/_standalone/data/skills/mindos-zh/SKILL.md +100 -104
- package/_standalone/data/skills/mindos-zh/references/write-supplement.md +119 -0
- package/_standalone/hooks/useAcpDetection.ts +1 -1
- package/_standalone/hooks/useAskChat.ts +248 -0
- package/_standalone/hooks/useAskPanel.ts +24 -4
- package/_standalone/hooks/useAskSession.ts +15 -0
- package/_standalone/lib/acp/types.ts +1 -1
- package/_standalone/lib/api.ts +3 -1
- package/_standalone/lib/core/types.ts +2 -0
- package/_standalone/lib/i18n/modules/ai-chat.ts +35 -13
- package/_standalone/lib/i18n/modules/features.ts +5 -5
- package/_standalone/lib/i18n/modules/knowledge.ts +86 -2
- package/_standalone/lib/i18n/modules/navigation.ts +6 -2
- package/_standalone/lib/i18n/modules/onboarding.ts +69 -29
- package/_standalone/lib/i18n/modules/panels.ts +78 -29
- package/_standalone/lib/i18n/modules/settings.ts +280 -24
- package/_standalone/lib/inbox-upload.ts +93 -0
- package/_standalone/lib/mcp-snippets.ts +5 -1
- package/_standalone/lib/settings-ai-client.ts +13 -12
- package/_standalone/lib/space-ai-init.ts +66 -0
- package/_standalone/lib/stores/McpStoreInit.tsx +18 -0
- package/_standalone/lib/stores/WalkthroughInit.tsx +20 -0
- package/_standalone/lib/stores/locale-store.ts +55 -0
- package/_standalone/lib/stores/mcp-store.ts +156 -0
- package/_standalone/lib/stores/walkthrough-store.ts +118 -0
- package/_standalone/package-lock.json +40 -8
- package/_standalone/package.json +3 -1
- package/_standalone/tsconfig.json +1 -1
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/api/acp/detect/route.ts +29 -20
- package/app/app/api/agent-activity/route.ts +1 -1
- package/app/app/api/ask/route.ts +105 -30
- package/app/app/api/ask-sessions/route.ts +1 -0
- package/app/app/api/bootstrap/route.ts +1 -3
- package/app/app/api/file/route.ts +34 -4
- package/app/app/api/inbox/route.ts +61 -0
- package/app/app/api/mcp/install/route.ts +2 -1
- package/app/app/api/mcp/status/route.ts +14 -6
- package/app/app/api/settings/list-models/route.ts +73 -53
- package/app/app/api/settings/route.ts +46 -55
- package/app/app/api/settings/test-key/route.ts +57 -114
- package/app/app/api/setup/route.ts +31 -21
- package/app/app/api/sync/route.ts +122 -12
- package/app/app/api/update-check/route.ts +2 -2
- package/app/app/globals.css +11 -1
- package/app/app/layout.tsx +2 -3
- package/app/app/login/page.tsx +1 -1
- package/app/app/view/[...path]/ViewPageClient.tsx +22 -37
- package/app/app/view/[...path]/not-found.tsx +1 -1
- package/app/components/ActivityBar.tsx +26 -10
- package/app/components/AskFab.tsx +1 -1
- package/app/components/AskModal.tsx +1 -1
- package/app/components/Backlinks.tsx +1 -1
- package/app/components/CreateSpaceModal.tsx +7 -55
- package/app/components/DirView.tsx +93 -11
- package/app/components/EchoSpotlight.tsx +1 -1
- package/app/components/ExportModal.tsx +1 -1
- package/app/components/FileTree.tsx +66 -80
- package/app/components/FindInPage.tsx +1 -1
- package/app/components/GuideCard.tsx +1 -1
- package/app/components/HomeContent.tsx +21 -14
- package/app/components/ImportModal.tsx +1 -1
- package/app/components/KeyboardShortcuts.tsx +1 -1
- package/app/components/MarkdownView.tsx +41 -16
- package/app/components/OnboardingView.tsx +1 -1
- package/app/components/OrganizeToast.tsx +1 -1
- package/app/components/Panel.tsx +82 -4
- package/app/components/QuickSuggestion.tsx +1 -1
- package/app/components/RightAgentDetailPanel.tsx +2 -2
- package/app/components/RightAskPanel.tsx +88 -22
- package/app/components/SearchModal.tsx +1 -1
- package/app/components/Sidebar.tsx +4 -4
- package/app/components/SidebarLayout.tsx +52 -16
- package/app/components/SpaceInitToast.tsx +1 -1
- package/app/components/SyncStatusBar.tsx +2 -2
- package/app/components/SystemPulse.tsx +12 -6
- package/app/components/TableOfContents.tsx +86 -39
- package/app/components/TrashPageClient.tsx +1 -1
- package/app/components/UpdateOverlay.tsx +2 -2
- package/app/components/agents/AgentActivitySection.tsx +225 -0
- package/app/components/agents/AgentDetailContent.tsx +234 -3
- package/app/components/agents/AgentsContentPage.tsx +13 -2
- package/app/components/agents/AgentsMcpSection.tsx +10 -16
- package/app/components/agents/AgentsOverviewSection.tsx +28 -27
- package/app/components/agents/AgentsPanelA2aTab.tsx +1 -1
- package/app/components/agents/AgentsPanelSessionsTab.tsx +6 -1
- package/app/components/agents/AgentsSkillsSection.tsx +1 -1
- package/app/components/agents/DiscoverAgentModal.tsx +1 -1
- package/app/components/agents/RecentActivityFeed.tsx +49 -88
- package/app/components/agents/agent-activity-shared.tsx +110 -0
- package/app/components/agents/agents-content-model.ts +2 -2
- package/app/components/ask/AgentSelectorCapsule.tsx +1 -1
- package/app/components/ask/AskContent.tsx +332 -486
- package/app/components/ask/AskHeader.tsx +61 -0
- package/app/components/ask/FileChip.tsx +9 -5
- package/app/components/ask/MessageList.tsx +88 -21
- package/app/components/ask/ModeCapsule.tsx +180 -0
- package/app/components/ask/ProviderModelCapsule.tsx +284 -0
- package/app/components/ask/SessionHistory.tsx +63 -10
- package/app/components/ask/SessionTabBar.tsx +1 -1
- package/app/components/ask/ThinkingBlock.tsx +1 -1
- package/app/components/ask/ToolCallBlock.tsx +28 -24
- package/app/components/changes/ChangesBanner.tsx +1 -1
- package/app/components/changes/ChangesContentPage.tsx +1 -1
- package/app/components/echo/EchoInsightCollapsible.tsx +1 -1
- package/app/components/echo/EchoSegmentNav.tsx +1 -1
- package/app/components/echo/EchoSegmentPageClient.tsx +1 -1
- package/app/components/explore/ExploreContent.tsx +1 -1
- package/app/components/help/HelpContent.tsx +2 -1
- package/app/components/home/InboxSection.tsx +268 -0
- package/app/components/panels/AgentsPanel.tsx +3 -2
- package/app/components/panels/AgentsPanelHubNav.tsx +2 -6
- package/app/components/panels/DiscoverPanel.tsx +1 -1
- package/app/components/panels/EchoPanel.tsx +1 -1
- package/app/components/panels/EchoSidebarStats.tsx +1 -1
- package/app/components/panels/ImportHistoryPanel.tsx +1 -1
- package/app/components/panels/PanelHeader.tsx +1 -1
- package/app/components/panels/PluginsPanel.tsx +1 -1
- package/app/components/panels/SearchPanel.tsx +5 -2
- package/app/components/panels/SyncPopover.tsx +1 -1
- package/app/components/panels/WorkflowsPanel.tsx +1 -1
- package/app/components/renderers/agent-inspector/AgentInspectorRenderer.tsx +18 -0
- package/app/components/renderers/todo/TodoRenderer.tsx +489 -75
- package/app/components/settings/AiTab.tsx +198 -127
- package/app/components/settings/AppearanceTab.tsx +48 -50
- package/app/components/settings/KnowledgeTab.tsx +92 -27
- package/app/components/settings/McpAgentInstall.tsx +95 -28
- package/app/components/settings/McpSkillsSection.tsx +2 -2
- package/app/components/settings/McpTab.tsx +498 -216
- package/app/components/settings/PluginsTab.tsx +1 -1
- package/app/components/settings/SettingsContent.tsx +17 -8
- package/app/components/settings/SyncTab.tsx +615 -230
- package/app/components/settings/UninstallTab.tsx +1 -1
- package/app/components/settings/UpdateTab.tsx +2 -2
- package/app/components/settings/types.ts +7 -5
- package/app/components/setup/StepAI.tsx +70 -49
- package/app/components/setup/StepAgents.tsx +113 -47
- package/app/components/setup/StepDots.tsx +1 -1
- package/app/components/setup/StepReview.tsx +186 -31
- package/app/components/setup/index.tsx +83 -48
- package/app/components/setup/types.ts +17 -8
- package/app/components/shared/ProviderSelect.tsx +134 -0
- package/app/components/walkthrough/WalkthroughOverlay.tsx +2 -2
- package/app/components/walkthrough/WalkthroughTooltip.tsx +2 -2
- package/app/components/walkthrough/index.ts +1 -1
- package/app/data/skills/mindos/SKILL.md +93 -93
- package/app/data/skills/mindos/references/write-supplement.md +119 -0
- package/app/data/skills/mindos-zh/SKILL.md +100 -104
- package/app/data/skills/mindos-zh/references/write-supplement.md +119 -0
- package/app/hooks/useAcpDetection.ts +1 -1
- package/app/hooks/useAskChat.ts +248 -0
- package/app/hooks/useAskPanel.ts +24 -4
- package/app/hooks/useAskSession.ts +15 -0
- package/app/lib/acp/types.ts +1 -1
- package/app/lib/actions.ts +13 -0
- package/app/lib/agent/log.ts +2 -0
- package/app/lib/agent/model.ts +69 -81
- package/app/lib/agent/prompt.ts +27 -0
- package/app/lib/agent/providers.ts +299 -0
- package/app/lib/agent/tools.ts +26 -4
- package/app/lib/api.ts +3 -1
- package/app/lib/core/agent-audit-log.ts +7 -0
- package/app/lib/core/fs-ops.ts +9 -4
- package/app/lib/core/inbox.ts +181 -0
- package/app/lib/core/index.ts +4 -0
- package/app/lib/core/tree.ts +3 -0
- package/app/lib/core/types.ts +2 -0
- package/app/lib/fs.ts +20 -2
- package/app/lib/i18n/modules/ai-chat.ts +35 -13
- package/app/lib/i18n/modules/features.ts +5 -5
- package/app/lib/i18n/modules/knowledge.ts +86 -2
- package/app/lib/i18n/modules/navigation.ts +6 -2
- package/app/lib/i18n/modules/onboarding.ts +69 -29
- package/app/lib/i18n/modules/panels.ts +78 -29
- package/app/lib/i18n/modules/settings.ts +280 -24
- package/app/lib/inbox-upload.ts +93 -0
- package/app/lib/mcp-agents.ts +7 -9
- package/app/lib/mcp-snippets.ts +5 -1
- package/app/lib/settings-ai-client.ts +13 -12
- package/app/lib/settings.ts +48 -33
- package/app/lib/space-ai-init.ts +66 -0
- package/app/lib/stores/LocaleStoreInit.tsx +18 -0
- package/app/lib/stores/McpStoreInit.tsx +18 -0
- package/app/lib/stores/WalkthroughInit.tsx +20 -0
- package/app/lib/stores/locale-store.ts +55 -0
- package/app/lib/stores/mcp-store.ts +156 -0
- package/app/lib/stores/walkthrough-store.ts +118 -0
- package/app/lib/types.ts +20 -0
- package/app/package.json +3 -1
- package/app/tsconfig.json +1 -1
- package/bin/cli.js +168 -1385
- package/bin/commands/agent.js +156 -20
- package/bin/commands/api.js +14 -11
- package/bin/commands/ask.js +79 -68
- package/bin/commands/build.js +26 -0
- package/bin/commands/config.js +170 -0
- package/bin/commands/dev.js +58 -0
- package/bin/commands/doctor.js +205 -0
- package/bin/commands/file.js +558 -40
- package/bin/commands/gateway.js +42 -0
- package/bin/commands/init-skills.js +56 -0
- package/bin/commands/logs.js +32 -0
- package/bin/commands/mcp-cmd.js +57 -0
- package/bin/commands/onboard.js +25 -0
- package/bin/commands/open.js +41 -0
- package/bin/commands/restart.js +48 -0
- package/bin/commands/search.js +16 -14
- package/bin/commands/space.js +100 -25
- package/bin/commands/start.js +262 -0
- package/bin/commands/status.js +2 -2
- package/bin/commands/stop.js +14 -0
- package/bin/commands/sync-cmd.js +134 -0
- package/bin/commands/token.js +98 -0
- package/bin/commands/uninstall.js +154 -0
- package/bin/commands/update.js +286 -0
- package/bin/lib/build.js +1 -1
- package/bin/lib/colors.js +8 -7
- package/bin/lib/command.js +37 -96
- package/bin/lib/config.js +5 -0
- package/bin/lib/csv.js +19 -0
- package/bin/lib/jsonc.js +12 -0
- package/bin/lib/markdown.js +69 -0
- package/bin/lib/mcp-agents.js +27 -8
- package/bin/lib/mcp-build.js +1 -1
- package/bin/lib/mcp-install.js +13 -4
- package/bin/lib/one-shot.js +88 -0
- package/bin/lib/path-expand.js +9 -0
- package/bin/lib/remote.js +65 -0
- package/bin/lib/repl.js +167 -0
- package/bin/lib/{utils.js → shell.js} +10 -26
- package/bin/lib/skill-check.js +1 -1
- package/bin/lib/sse-stream.js +167 -0
- package/bin/lib/sync.js +140 -34
- package/mcp/README.md +2 -2
- package/mcp/dist/index.cjs +43 -43
- package/mcp/package.json +1 -1
- package/mcp/src/index.ts +77 -61
- package/package.json +2 -2
- package/scripts/setup.js +183 -121
- package/skills/mindos/SKILL.md +93 -93
- package/skills/mindos/references/preference-capture.md +4 -4
- package/skills/mindos/references/write-supplement.md +2 -2
- package/skills/mindos-zh/SKILL.md +100 -104
- package/skills/mindos-zh/references/preference-capture.md +4 -4
- package/skills/mindos-zh/references/write-supplement.md +2 -2
- package/templates/empty/INSTRUCTION.md +0 -1
- package/templates/en/INSTRUCTION.md +0 -1
- package/templates/template-generation-skill.md +0 -1
- package/templates/zh/INSTRUCTION.md +0 -1
- package/_standalone/.next/server/chunks/1473.js +0 -52
- package/_standalone/.next/server/chunks/248.js +0 -15
- package/_standalone/.next/server/chunks/359.js +0 -2
- package/_standalone/.next/server/chunks/4931.js +0 -202
- package/_standalone/.next/server/chunks/7670.js +0 -1
- package/_standalone/.next/static/chunks/1038-ed04d6651ec92312.js +0 -1
- package/_standalone/.next/static/chunks/1263-6df1734e4273adb1.js +0 -25
- package/_standalone/.next/static/chunks/275-ebcaaedabe706903.js +0 -1
- package/_standalone/.next/static/chunks/3637.4bcd01a4db78b894.js +0 -1
- package/_standalone/.next/static/chunks/5637-b97c869adf70c82e.js +0 -1
- package/_standalone/.next/static/chunks/5681-a53362a1cd629dc6.js +0 -1
- package/_standalone/.next/static/chunks/9602-35ca17b688f1a4fe.js +0 -1
- package/_standalone/.next/static/chunks/9670-d59e4d45ed705f58.js +0 -6
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/_global-error/page-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-519d4da1142db5ef.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/page-b709cf3103321609.js +0 -5
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/config/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/install/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/session/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/auth/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/backlinks/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/changes/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/export/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/import/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/files/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/git/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/graph/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/health/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/init/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/monitoring/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/recent-files/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/restart/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/search/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/skills/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/sync/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/tree-version/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/uninstall/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-check/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-status/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/workflows/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/changes/page-def5210095f8698d.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-be28eff31b1a186e.js +0 -11
- package/_standalone/.next/static/chunks/app/echo/page-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/explore/page-e4b8098dca200389.js +0 -4
- package/_standalone/.next/static/chunks/app/help/page-d5e57d73d94bad19.js +0 -1
- package/_standalone/.next/static/chunks/app/layout-d91cdbe2ecf135e1.js +0 -173
- package/_standalone/.next/static/chunks/app/login/page-321875768b70938a.js +0 -1
- package/_standalone/.next/static/chunks/app/page-718fdf170428b43c.js +0 -7
- package/_standalone/.next/static/chunks/app/setup/page-01ab1f549d636057.js +0 -1
- package/_standalone/.next/static/chunks/app/trash/page-89b1430cc8a16f18.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/not-found-f22c513bbc348cc8.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-6e3dc47699a01de1.js +0 -12
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/webpack-3489a2b6c2882b0c.js +0 -1
- package/_standalone/.next/static/css/f16595bc58a16d5d.css +0 -1
- package/_standalone/.next/static/ushZ_NJ8rE3rG5hZfaYOX/_buildManifest.js +0 -1
- package/_standalone/components/walkthrough/WalkthroughProvider.tsx +0 -133
- package/_standalone/hooks/useMcpData.tsx +0 -169
- package/_standalone/lib/i18n-en.ts +0 -2
- package/_standalone/lib/i18n-zh.ts +0 -2
- package/_standalone/lib/types.ts +0 -70
- package/app/components/walkthrough/WalkthroughProvider.tsx +0 -133
- package/app/hooks/useMcpData.tsx +0 -169
- package/app/lib/LocaleContext.tsx +0 -60
- package/app/lib/i18n-en.ts +0 -2
- package/app/lib/i18n-zh.ts +0 -2
- /package/_standalone/.next/static/{ushZ_NJ8rE3rG5hZfaYOX → Ij3PFh-a0zi5K_ANoSAW0}/_ssgManifest.js +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useEffect, useLayoutEffect, useRef, useState, useCallback } from 'react';
|
|
4
|
-
import {
|
|
5
|
-
import { useLocale } from '@/lib/
|
|
6
|
-
import type {
|
|
3
|
+
import { useEffect, useLayoutEffect, useRef, useState, useCallback, useMemo } from 'react';
|
|
4
|
+
import { Send, StopCircle, X, Plus, FileText, ImageIcon } from 'lucide-react';
|
|
5
|
+
import { useLocale } from '@/lib/stores/locale-store';
|
|
6
|
+
import type { AskMode } from '@/lib/types';
|
|
7
|
+
import ModeCapsule, { getPersistedMode } from '@/components/ask/ModeCapsule';
|
|
7
8
|
import { useAskSession } from '@/hooks/useAskSession';
|
|
8
9
|
import { useFileUpload } from '@/hooks/useFileUpload';
|
|
9
10
|
import { useImageUpload } from '@/hooks/useImageUpload';
|
|
@@ -15,10 +16,12 @@ import MentionPopover from '@/components/ask/MentionPopover';
|
|
|
15
16
|
import SlashCommandPopover from '@/components/ask/SlashCommandPopover';
|
|
16
17
|
import SessionHistory from '@/components/ask/SessionHistory';
|
|
17
18
|
import SessionTabBar from '@/components/ask/SessionTabBar';
|
|
19
|
+
import AskHeader from '@/components/ask/AskHeader';
|
|
18
20
|
import FileChip from '@/components/ask/FileChip';
|
|
19
21
|
import AgentSelectorCapsule from '@/components/ask/AgentSelectorCapsule';
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
+
import ProviderModelCapsule, { getPersistedProvider } from '@/components/ask/ProviderModelCapsule';
|
|
23
|
+
import type { ProviderId } from '@/lib/agent/providers';
|
|
24
|
+
import { useAskChat } from '@/hooks/useAskChat';
|
|
22
25
|
import { cn } from '@/lib/utils';
|
|
23
26
|
import { useAcpDetection } from '@/hooks/useAcpDetection';
|
|
24
27
|
import type { AcpAgentSelection } from '@/hooks/useAskModal';
|
|
@@ -26,23 +29,32 @@ import type { AcpAgentSelection } from '@/hooks/useAskModal';
|
|
|
26
29
|
/** Textarea auto-grows with content up to this many visible lines, then scrolls */
|
|
27
30
|
const TEXTAREA_MAX_VISIBLE_LINES = 8;
|
|
28
31
|
|
|
32
|
+
/** Per-element cached metrics to avoid getComputedStyle on every keystroke */
|
|
33
|
+
const _metricsCache = new WeakMap<HTMLTextAreaElement, { maxH: number }>();
|
|
34
|
+
|
|
29
35
|
/** Auto-size textarea height to fit content, capped at maxVisibleLines */
|
|
30
36
|
function syncTextareaToContent(el: HTMLTextAreaElement, maxVisibleLines: number): void {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
let cached = _metricsCache.get(el);
|
|
38
|
+
if (!cached) {
|
|
39
|
+
const style = getComputedStyle(el);
|
|
40
|
+
const parsedLh = parseFloat(style.lineHeight);
|
|
41
|
+
const parsedFs = parseFloat(style.fontSize);
|
|
42
|
+
const fontSize = Number.isFinite(parsedFs) ? parsedFs : 14;
|
|
43
|
+
const lineHeight = Number.isFinite(parsedLh) ? parsedLh : fontSize * 1.375;
|
|
44
|
+
const pad =
|
|
45
|
+
(Number.isFinite(parseFloat(style.paddingTop)) ? parseFloat(style.paddingTop) : 0) +
|
|
46
|
+
(Number.isFinite(parseFloat(style.paddingBottom)) ? parseFloat(style.paddingBottom) : 0);
|
|
47
|
+
const maxH = lineHeight * maxVisibleLines + pad;
|
|
48
|
+
if (!Number.isFinite(maxH) || maxH <= 0) return;
|
|
49
|
+
cached = { maxH };
|
|
50
|
+
_metricsCache.set(el, cached);
|
|
51
|
+
}
|
|
52
|
+
const { maxH } = cached;
|
|
53
|
+
el.style.height = 'auto';
|
|
54
|
+
const contentH = el.scrollHeight;
|
|
55
|
+
const next = Math.min(contentH, maxH);
|
|
56
|
+
el.style.height = `${next}px`;
|
|
57
|
+
el.style.overflowY = contentH > maxH ? 'auto' : 'hidden';
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
interface AskContentProps {
|
|
@@ -70,42 +82,83 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
70
82
|
|
|
71
83
|
const inputRef = useRef<HTMLTextAreaElement>(null);
|
|
72
84
|
const imageInputRef = useRef<HTMLInputElement>(null);
|
|
73
|
-
const abortRef = useRef<AbortController | null>(null);
|
|
74
|
-
const firstMessageFired = useRef(false);
|
|
75
85
|
const { t } = useLocale();
|
|
76
86
|
const [mounted, setMounted] = useState(false);
|
|
77
87
|
useEffect(() => setMounted(true), []);
|
|
78
88
|
|
|
79
89
|
const [input, setInput] = useState('');
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
const [reconnectAttempt, setReconnectAttempt] = useState(0);
|
|
83
|
-
const reconnectMaxRef = useRef(3);
|
|
90
|
+
const inputValueRef = useRef('');
|
|
91
|
+
inputValueRef.current = input;
|
|
84
92
|
const [attachedFiles, setAttachedFiles] = useState<string[]>([]);
|
|
93
|
+
const attachedFilesRef = useRef(attachedFiles);
|
|
94
|
+
attachedFilesRef.current = attachedFiles;
|
|
85
95
|
const [showHistory, setShowHistory] = useState(false);
|
|
86
96
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
87
97
|
const [showAttachMenu, setShowAttachMenu] = useState(false);
|
|
88
98
|
|
|
89
99
|
const [selectedSkill, setSelectedSkill] = useState<SlashItem | null>(null);
|
|
100
|
+
const selectedSkillRef = useRef(selectedSkill);
|
|
101
|
+
selectedSkillRef.current = selectedSkill;
|
|
90
102
|
const [selectedAcpAgent, setSelectedAcpAgent] = useState<AcpAgentSelection | null>(null);
|
|
103
|
+
const selectedAcpAgentRef = useRef(selectedAcpAgent);
|
|
104
|
+
selectedAcpAgentRef.current = selectedAcpAgent;
|
|
105
|
+
const [chatMode, setChatMode] = useState<AskMode>('agent');
|
|
106
|
+
const [providerOverride, setProviderOverride] = useState<ProviderId | null>(null);
|
|
107
|
+
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
setChatMode(getPersistedMode());
|
|
110
|
+
setProviderOverride(getPersistedProvider());
|
|
111
|
+
}, []);
|
|
91
112
|
|
|
92
113
|
const session = useAskSession(currentFile);
|
|
114
|
+
const sessionRef = useRef(session);
|
|
115
|
+
sessionRef.current = session;
|
|
93
116
|
const upload = useFileUpload();
|
|
117
|
+
const uploadRef = useRef(upload);
|
|
118
|
+
uploadRef.current = upload;
|
|
94
119
|
const imageUpload = useImageUpload();
|
|
95
120
|
const mention = useMention();
|
|
96
121
|
const slash = useSlashCommand();
|
|
97
122
|
const acpDetection = useAcpDetection();
|
|
98
123
|
|
|
124
|
+
const imageUploadRef = useRef(imageUpload);
|
|
125
|
+
imageUploadRef.current = imageUpload;
|
|
126
|
+
const mentionRef = useRef(mention);
|
|
127
|
+
mentionRef.current = mention;
|
|
128
|
+
const slashRef = useRef(slash);
|
|
129
|
+
slashRef.current = slash;
|
|
130
|
+
|
|
131
|
+
const resetInputState = useCallback(() => {
|
|
132
|
+
setInput('');
|
|
133
|
+
setSelectedSkill(null);
|
|
134
|
+
setSelectedAcpAgent(null);
|
|
135
|
+
setAttachedFiles(currentFile ? [currentFile] : []);
|
|
136
|
+
}, [currentFile]);
|
|
137
|
+
|
|
138
|
+
const chatRefs = useRef({ inputValueRef, mentionRef, slashRef, imageUploadRef, sessionRef, uploadRef, selectedSkillRef, selectedAcpAgentRef, attachedFilesRef });
|
|
139
|
+
const chat = useAskChat({
|
|
140
|
+
currentFile,
|
|
141
|
+
chatMode,
|
|
142
|
+
providerOverride,
|
|
143
|
+
onFirstMessage,
|
|
144
|
+
refs: chatRefs.current,
|
|
145
|
+
errorLabels: { noResponse: t.ask.errorNoResponse, stopped: t.ask.stopped },
|
|
146
|
+
resetInputState,
|
|
147
|
+
});
|
|
148
|
+
const { isLoading, loadingPhase, reconnectAttempt, reconnectMaxRef } = chat;
|
|
149
|
+
const handleSubmit = chat.submit;
|
|
150
|
+
const handleStop = chat.stop;
|
|
151
|
+
|
|
99
152
|
useEffect(() => {
|
|
100
153
|
const handler = (e: Event) => {
|
|
101
154
|
const files = (e as CustomEvent).detail?.files;
|
|
102
155
|
if (Array.isArray(files) && files.length > 0) {
|
|
103
|
-
|
|
156
|
+
uploadRef.current.injectFiles(files);
|
|
104
157
|
}
|
|
105
158
|
};
|
|
106
159
|
window.addEventListener('mindos:inject-ask-files', handler);
|
|
107
160
|
return () => window.removeEventListener('mindos:inject-ask-files', handler);
|
|
108
|
-
}, [
|
|
161
|
+
}, []);
|
|
109
162
|
|
|
110
163
|
// Focus and init session when becoming visible (edge-triggered for panel, level-triggered for modal)
|
|
111
164
|
const prevVisibleRef = useRef(false);
|
|
@@ -122,7 +175,7 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
122
175
|
setTimeout(() => inputRef.current?.focus(), 50);
|
|
123
176
|
void session.initSessions();
|
|
124
177
|
setInput(initialMessage || '');
|
|
125
|
-
firstMessageFired.current = false;
|
|
178
|
+
chat.firstMessageFired.current = false;
|
|
126
179
|
setAttachedFiles(currentFile ? [currentFile] : []);
|
|
127
180
|
upload.clearAttachments();
|
|
128
181
|
imageUpload.clearImages();
|
|
@@ -136,7 +189,7 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
136
189
|
setAttachedFiles(currentFile ? [currentFile] : []);
|
|
137
190
|
} else if (!visible && variant === 'modal') {
|
|
138
191
|
// Modal: abort streaming on close
|
|
139
|
-
abortRef.current?.abort();
|
|
192
|
+
chat.abortRef.current?.abort();
|
|
140
193
|
}
|
|
141
194
|
prevVisibleRef.current = visible;
|
|
142
195
|
prevFileRef.current = currentFile;
|
|
@@ -147,28 +200,32 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
147
200
|
useEffect(() => {
|
|
148
201
|
if (!visible || !session.activeSessionId) return;
|
|
149
202
|
const msgs = session.messages;
|
|
150
|
-
if (isLoading && msgs.length > 0) {
|
|
203
|
+
if (chat.isLoading && msgs.length > 0) {
|
|
151
204
|
const last = msgs[msgs.length - 1];
|
|
152
205
|
if (last.role === 'assistant' && !last.content.trim() && (!last.parts || last.parts.length === 0)) return;
|
|
153
206
|
}
|
|
154
207
|
session.persistSession(msgs, session.activeSessionId);
|
|
155
208
|
return () => session.clearPersistTimer();
|
|
156
209
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
157
|
-
}, [visible, session.messages, session.activeSessionId, isLoading]);
|
|
210
|
+
}, [visible, session.messages, session.activeSessionId, chat.isLoading]);
|
|
158
211
|
|
|
159
|
-
// Esc to close
|
|
212
|
+
// Esc to close modal or exit focus mode
|
|
160
213
|
useEffect(() => {
|
|
161
|
-
if (
|
|
214
|
+
if (!visible) return;
|
|
215
|
+
const isModal = variant === 'modal';
|
|
216
|
+
const isFocused = variant === 'panel' && maximized;
|
|
217
|
+
if (!isModal && !isFocused) return;
|
|
162
218
|
const handler = (e: KeyboardEvent) => {
|
|
163
219
|
if (e.key === 'Escape') {
|
|
164
|
-
if (
|
|
165
|
-
if (
|
|
166
|
-
|
|
220
|
+
if (mentionRef.current.mentionQuery !== null) { mentionRef.current.resetMention(); return; }
|
|
221
|
+
if (slashRef.current.slashQuery !== null) { slashRef.current.resetSlash(); return; }
|
|
222
|
+
if (isFocused && onMaximize) { onMaximize(); return; }
|
|
223
|
+
if (isModal && onClose) { onClose(); }
|
|
167
224
|
}
|
|
168
225
|
};
|
|
169
226
|
window.addEventListener('keydown', handler);
|
|
170
227
|
return () => window.removeEventListener('keydown', handler);
|
|
171
|
-
}, [variant, visible, onClose,
|
|
228
|
+
}, [variant, visible, onClose, maximized, onMaximize]);
|
|
172
229
|
|
|
173
230
|
// Close attach menu on any outside click
|
|
174
231
|
useEffect(() => {
|
|
@@ -188,6 +245,14 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
188
245
|
syncTextareaToContent(el, TEXTAREA_MAX_VISIBLE_LINES);
|
|
189
246
|
}, [input, isLoading, visible]);
|
|
190
247
|
|
|
248
|
+
useEffect(() => {
|
|
249
|
+
const el = inputRef.current;
|
|
250
|
+
if (!el) return;
|
|
251
|
+
const handler = () => _metricsCache.delete(el);
|
|
252
|
+
window.addEventListener('resize', handler);
|
|
253
|
+
return () => window.removeEventListener('resize', handler);
|
|
254
|
+
}, []);
|
|
255
|
+
|
|
191
256
|
const mentionTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
192
257
|
const slashTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
193
258
|
const handleInputChange = useCallback((val: string, cursorPos?: number) => {
|
|
@@ -195,9 +260,9 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
195
260
|
const pos = cursorPos ?? val.length;
|
|
196
261
|
if (mentionTimerRef.current) clearTimeout(mentionTimerRef.current);
|
|
197
262
|
if (slashTimerRef.current) clearTimeout(slashTimerRef.current);
|
|
198
|
-
mentionTimerRef.current = setTimeout(() =>
|
|
199
|
-
slashTimerRef.current = setTimeout(() =>
|
|
200
|
-
}, [
|
|
263
|
+
mentionTimerRef.current = setTimeout(() => mentionRef.current.updateMentionFromInput(val, pos), 80);
|
|
264
|
+
slashTimerRef.current = setTimeout(() => slashRef.current.updateSlashFromInput(val, pos), 80);
|
|
265
|
+
}, []);
|
|
201
266
|
|
|
202
267
|
useEffect(() => {
|
|
203
268
|
return () => {
|
|
@@ -208,273 +273,111 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
208
273
|
|
|
209
274
|
const selectMention = useCallback((filePath: string) => {
|
|
210
275
|
const el = inputRef.current;
|
|
211
|
-
const
|
|
212
|
-
const
|
|
276
|
+
const val = inputValueRef.current;
|
|
277
|
+
const cursorPos = el?.selectionStart ?? val.length;
|
|
278
|
+
const before = val.slice(0, cursorPos);
|
|
213
279
|
const atIdx = before.lastIndexOf('@');
|
|
214
|
-
const newVal =
|
|
280
|
+
const newVal = val.slice(0, atIdx) + val.slice(cursorPos);
|
|
215
281
|
setInput(newVal);
|
|
216
|
-
|
|
217
|
-
if (!
|
|
282
|
+
mentionRef.current.resetMention();
|
|
283
|
+
if (!attachedFilesRef.current.includes(filePath)) {
|
|
218
284
|
setAttachedFiles(prev => [...prev, filePath]);
|
|
219
285
|
}
|
|
220
286
|
setTimeout(() => {
|
|
221
287
|
inputRef.current?.focus();
|
|
222
288
|
inputRef.current?.setSelectionRange(atIdx, atIdx);
|
|
223
289
|
}, 0);
|
|
224
|
-
}, [
|
|
290
|
+
}, []);
|
|
225
291
|
|
|
226
292
|
const selectSlashCommand = useCallback((item: SlashItem) => {
|
|
227
293
|
const el = inputRef.current;
|
|
228
|
-
const
|
|
229
|
-
const
|
|
294
|
+
const val = inputValueRef.current;
|
|
295
|
+
const cursorPos = el?.selectionStart ?? val.length;
|
|
296
|
+
const before = val.slice(0, cursorPos);
|
|
230
297
|
const slashIdx = before.lastIndexOf('/');
|
|
231
|
-
const newVal =
|
|
298
|
+
const newVal = val.slice(0, slashIdx) + val.slice(cursorPos);
|
|
232
299
|
setInput(newVal);
|
|
233
300
|
setSelectedSkill(item);
|
|
234
|
-
|
|
301
|
+
slashRef.current.resetSlash();
|
|
235
302
|
setTimeout(() => {
|
|
236
303
|
inputRef.current?.focus();
|
|
237
304
|
inputRef.current?.setSelectionRange(slashIdx, slashIdx);
|
|
238
305
|
}, 0);
|
|
239
|
-
}, [
|
|
306
|
+
}, []);
|
|
307
|
+
|
|
308
|
+
const selectMentionRef = useRef(selectMention);
|
|
309
|
+
selectMentionRef.current = selectMention;
|
|
310
|
+
const selectSlashRef = useRef(selectSlashCommand);
|
|
311
|
+
selectSlashRef.current = selectSlashCommand;
|
|
240
312
|
|
|
241
313
|
const handleInputKeyDown = useCallback(
|
|
242
314
|
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
|
243
|
-
|
|
315
|
+
const m = mentionRef.current;
|
|
316
|
+
const s = slashRef.current;
|
|
317
|
+
if (m.mentionQuery !== null) {
|
|
244
318
|
if (e.key === 'Escape') {
|
|
245
319
|
e.preventDefault();
|
|
246
|
-
|
|
320
|
+
m.resetMention();
|
|
247
321
|
return;
|
|
248
322
|
}
|
|
249
323
|
if (e.key === 'ArrowDown') {
|
|
250
324
|
e.preventDefault();
|
|
251
|
-
|
|
325
|
+
m.navigateMention('down');
|
|
252
326
|
} else if (e.key === 'ArrowUp') {
|
|
253
327
|
e.preventDefault();
|
|
254
|
-
|
|
328
|
+
m.navigateMention('up');
|
|
255
329
|
} else if (e.key === 'Enter' || e.key === 'Tab') {
|
|
256
330
|
if (e.key === 'Enter' && (e.shiftKey || e.nativeEvent.isComposing)) return;
|
|
257
|
-
if (
|
|
331
|
+
if (m.mentionResults.length > 0) {
|
|
258
332
|
e.preventDefault();
|
|
259
|
-
|
|
333
|
+
selectMentionRef.current(m.mentionResults[m.mentionIndex]);
|
|
260
334
|
}
|
|
261
335
|
}
|
|
262
336
|
return;
|
|
263
337
|
}
|
|
264
|
-
if (
|
|
338
|
+
if (s.slashQuery !== null) {
|
|
265
339
|
if (e.key === 'Escape') {
|
|
266
340
|
e.preventDefault();
|
|
267
|
-
|
|
341
|
+
s.resetSlash();
|
|
268
342
|
return;
|
|
269
343
|
}
|
|
270
344
|
if (e.key === 'ArrowDown') {
|
|
271
345
|
e.preventDefault();
|
|
272
|
-
|
|
346
|
+
s.navigateSlash('down');
|
|
273
347
|
} else if (e.key === 'ArrowUp') {
|
|
274
348
|
e.preventDefault();
|
|
275
|
-
|
|
349
|
+
s.navigateSlash('up');
|
|
276
350
|
} else if (e.key === 'Enter' || e.key === 'Tab') {
|
|
277
351
|
if (e.key === 'Enter' && (e.shiftKey || e.nativeEvent.isComposing)) return;
|
|
278
|
-
if (
|
|
352
|
+
if (s.slashResults.length > 0) {
|
|
279
353
|
e.preventDefault();
|
|
280
|
-
|
|
354
|
+
selectSlashRef.current(s.slashResults[s.slashIndex]);
|
|
281
355
|
}
|
|
282
356
|
}
|
|
283
357
|
return;
|
|
284
358
|
}
|
|
285
|
-
if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing && !
|
|
359
|
+
if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing && !chat.isLoadingRef.current && (inputValueRef.current.trim() || imageUploadRef.current.images.length > 0)) {
|
|
286
360
|
e.preventDefault();
|
|
287
361
|
(e.currentTarget as HTMLTextAreaElement).form?.requestSubmit();
|
|
288
362
|
}
|
|
289
363
|
},
|
|
290
|
-
[
|
|
364
|
+
[],
|
|
291
365
|
);
|
|
292
366
|
|
|
293
|
-
const handleStop = useCallback(() => { abortRef.current?.abort(); }, []);
|
|
294
|
-
|
|
295
|
-
const handleSubmit = useCallback(async (e: React.FormEvent) => {
|
|
296
|
-
e.preventDefault();
|
|
297
|
-
if (mention.mentionQuery !== null || slash.slashQuery !== null) return;
|
|
298
|
-
const text = input.trim();
|
|
299
|
-
if ((!text && imageUpload.images.length === 0) || isLoading) return;
|
|
300
|
-
|
|
301
|
-
const pendingImages = imageUpload.images.length > 0 ? [...imageUpload.images] : undefined;
|
|
302
|
-
const userMsg: Message = {
|
|
303
|
-
role: 'user',
|
|
304
|
-
content: text, // No [ACP:] prefix — pass clean text
|
|
305
|
-
timestamp: Date.now(),
|
|
306
|
-
...(selectedSkill && { skillName: selectedSkill.name }),
|
|
307
|
-
...(pendingImages && { images: pendingImages }),
|
|
308
|
-
};
|
|
309
|
-
imageUpload.clearImages();
|
|
310
|
-
const requestMessages = [...session.messages, userMsg];
|
|
311
|
-
session.setMessages([...requestMessages, { role: 'assistant', content: '', timestamp: Date.now() }]);
|
|
312
|
-
setInput('');
|
|
313
|
-
setSelectedSkill(null);
|
|
314
|
-
setSelectedAcpAgent(null);
|
|
315
|
-
if (onFirstMessage && !firstMessageFired.current) {
|
|
316
|
-
firstMessageFired.current = true;
|
|
317
|
-
onFirstMessage();
|
|
318
|
-
}
|
|
319
|
-
setAttachedFiles(currentFile ? [currentFile] : []);
|
|
320
|
-
setIsLoading(true);
|
|
321
|
-
setLoadingPhase('connecting');
|
|
322
|
-
setReconnectAttempt(0);
|
|
323
|
-
|
|
324
|
-
const controller = new AbortController();
|
|
325
|
-
abortRef.current = controller;
|
|
326
|
-
|
|
327
|
-
let maxRetries = 3;
|
|
328
|
-
try {
|
|
329
|
-
const stored = localStorage.getItem('mindos-reconnect-retries');
|
|
330
|
-
if (stored !== null) { const n = parseInt(stored, 10); if (Number.isFinite(n)) maxRetries = Math.max(0, Math.min(10, n)); }
|
|
331
|
-
} catch { /* localStorage unavailable */ }
|
|
332
|
-
reconnectMaxRef.current = maxRetries;
|
|
333
|
-
|
|
334
|
-
const requestBody = JSON.stringify({
|
|
335
|
-
messages: requestMessages,
|
|
336
|
-
currentFile,
|
|
337
|
-
attachedFiles,
|
|
338
|
-
uploadedFiles: upload.localAttachments.map(f => ({
|
|
339
|
-
name: f.name,
|
|
340
|
-
content: f.content.length > 20_000
|
|
341
|
-
? f.content.slice(0, 20_000) + '\n\n[...truncated to first ~20000 chars]'
|
|
342
|
-
: f.content,
|
|
343
|
-
})),
|
|
344
|
-
selectedAcpAgent, // Send structured field instead of text prefix
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
const doFetch = async (): Promise<{ finalMessage: Message }> => {
|
|
348
|
-
const res = await fetch('/api/ask', {
|
|
349
|
-
method: 'POST',
|
|
350
|
-
headers: { 'Content-Type': 'application/json' },
|
|
351
|
-
body: requestBody,
|
|
352
|
-
signal: controller.signal,
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
if (!res.ok) {
|
|
356
|
-
let errorMsg = `Request failed (${res.status})`;
|
|
357
|
-
try {
|
|
358
|
-
const errBody = await res.json() as { error?: { message?: string } | string; message?: string };
|
|
359
|
-
if (typeof errBody?.error === 'string' && errBody.error.trim()) {
|
|
360
|
-
errorMsg = errBody.error;
|
|
361
|
-
} else if (typeof errBody?.error === 'object' && typeof errBody.error?.message === 'string' && errBody.error.message.trim()) {
|
|
362
|
-
errorMsg = errBody.error.message;
|
|
363
|
-
} else if (typeof errBody?.message === 'string' && errBody.message.trim()) {
|
|
364
|
-
errorMsg = errBody.message;
|
|
365
|
-
}
|
|
366
|
-
} catch (err) { console.warn("[AskContent] error body parse failed:", err); }
|
|
367
|
-
const err = new Error(errorMsg);
|
|
368
|
-
(err as Error & { httpStatus?: number }).httpStatus = res.status;
|
|
369
|
-
throw err;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
if (!res.body) throw new Error('No response body');
|
|
373
|
-
|
|
374
|
-
setLoadingPhase('thinking');
|
|
375
|
-
|
|
376
|
-
const finalMessage = await consumeUIMessageStream(
|
|
377
|
-
res.body,
|
|
378
|
-
(msg) => {
|
|
379
|
-
setLoadingPhase('streaming');
|
|
380
|
-
session.setMessages(prev => {
|
|
381
|
-
const updated = [...prev];
|
|
382
|
-
updated[updated.length - 1] = msg;
|
|
383
|
-
return updated;
|
|
384
|
-
});
|
|
385
|
-
},
|
|
386
|
-
controller.signal,
|
|
387
|
-
);
|
|
388
|
-
return { finalMessage };
|
|
389
|
-
};
|
|
390
|
-
|
|
391
|
-
try {
|
|
392
|
-
let lastError: Error | null = null;
|
|
393
|
-
|
|
394
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
395
|
-
if (controller.signal.aborted) break;
|
|
396
|
-
|
|
397
|
-
if (attempt > 0) {
|
|
398
|
-
setReconnectAttempt(attempt);
|
|
399
|
-
setLoadingPhase('reconnecting');
|
|
400
|
-
session.setMessages(prev => {
|
|
401
|
-
const updated = [...prev];
|
|
402
|
-
updated[updated.length - 1] = { role: 'assistant', content: '', timestamp: Date.now() };
|
|
403
|
-
return updated;
|
|
404
|
-
});
|
|
405
|
-
await sleep(retryDelay(attempt - 1), controller.signal);
|
|
406
|
-
setLoadingPhase('connecting');
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
try {
|
|
410
|
-
const { finalMessage } = await doFetch();
|
|
411
|
-
if (!finalMessage.content.trim() && (!finalMessage.parts || finalMessage.parts.length === 0)) {
|
|
412
|
-
session.setMessages(prev => {
|
|
413
|
-
const updated = [...prev];
|
|
414
|
-
updated[updated.length - 1] = { role: 'assistant', content: `__error__${t.ask.errorNoResponse}` };
|
|
415
|
-
return updated;
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
return;
|
|
419
|
-
} catch (err) {
|
|
420
|
-
lastError = err instanceof Error ? err : new Error(String(err));
|
|
421
|
-
const httpStatus = (err as Error & { httpStatus?: number }).httpStatus;
|
|
422
|
-
if (!isRetryableError(err, httpStatus) || attempt >= maxRetries) break;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
if (lastError) throw lastError;
|
|
427
|
-
} catch (err) {
|
|
428
|
-
if ((err as Error).name === 'AbortError') {
|
|
429
|
-
session.setMessages(prev => {
|
|
430
|
-
const updated = [...prev];
|
|
431
|
-
const lastIdx = updated.length - 1;
|
|
432
|
-
if (lastIdx >= 0 && updated[lastIdx].role === 'assistant') {
|
|
433
|
-
const last = updated[lastIdx];
|
|
434
|
-
const hasContent = last.content.trim() || (last.parts && last.parts.length > 0);
|
|
435
|
-
if (!hasContent) {
|
|
436
|
-
updated[lastIdx] = { role: 'assistant', content: `__error__${t.ask.stopped}` };
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
return updated;
|
|
440
|
-
});
|
|
441
|
-
} else {
|
|
442
|
-
const errMsg = err instanceof Error ? err.message : 'Something went wrong';
|
|
443
|
-
session.setMessages(prev => {
|
|
444
|
-
const updated = [...prev];
|
|
445
|
-
const lastIdx = updated.length - 1;
|
|
446
|
-
if (lastIdx >= 0 && updated[lastIdx].role === 'assistant') {
|
|
447
|
-
const last = updated[lastIdx];
|
|
448
|
-
const hasContent = last.content.trim() || (last.parts && last.parts.length > 0);
|
|
449
|
-
if (!hasContent) {
|
|
450
|
-
updated[lastIdx] = { role: 'assistant', content: `__error__${errMsg}` };
|
|
451
|
-
return updated;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
return [...updated, { role: 'assistant', content: `__error__${errMsg}` }];
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
} finally {
|
|
458
|
-
setIsLoading(false);
|
|
459
|
-
setReconnectAttempt(0);
|
|
460
|
-
abortRef.current = null;
|
|
461
|
-
}
|
|
462
|
-
}, [input, session, isLoading, currentFile, attachedFiles, upload.localAttachments, imageUpload.images, imageUpload.clearImages, mention.mentionQuery, slash.slashQuery, selectedSkill, selectedAcpAgent, t.ask.errorNoResponse, t.ask.stopped, onFirstMessage]);
|
|
463
|
-
|
|
464
367
|
const handleResetSession = useCallback(() => {
|
|
465
|
-
if (
|
|
466
|
-
|
|
368
|
+
if (chat.isLoadingRef.current) return;
|
|
369
|
+
sessionRef.current.resetSession();
|
|
467
370
|
setInput('');
|
|
468
371
|
setAttachedFiles(currentFile ? [currentFile] : []);
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
372
|
+
uploadRef.current.clearAttachments();
|
|
373
|
+
imageUploadRef.current.clearImages();
|
|
374
|
+
mentionRef.current.resetMention();
|
|
375
|
+
slashRef.current.resetSlash();
|
|
473
376
|
setSelectedSkill(null);
|
|
474
377
|
setSelectedAcpAgent(null);
|
|
475
378
|
setShowHistory(false);
|
|
476
379
|
setTimeout(() => inputRef.current?.focus(), 0);
|
|
477
|
-
}, [
|
|
380
|
+
}, [currentFile]);
|
|
478
381
|
|
|
479
382
|
const handleDragOver = useCallback((e: React.DragEvent) => {
|
|
480
383
|
// Accept mindos file paths and image drops
|
|
@@ -490,84 +393,67 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
490
393
|
const handleDrop = useCallback(async (e: React.DragEvent) => {
|
|
491
394
|
e.preventDefault();
|
|
492
395
|
setIsDragOver(false);
|
|
493
|
-
// Try mindos file path first
|
|
494
396
|
const filePath = e.dataTransfer.getData('text/mindos-path');
|
|
495
|
-
if (filePath
|
|
496
|
-
|
|
397
|
+
if (filePath) {
|
|
398
|
+
const pathType = e.dataTransfer.getData('text/mindos-type');
|
|
399
|
+
const key = pathType === 'directory' ? filePath.replace(/\/?$/, '/') : filePath;
|
|
400
|
+
if (!attachedFilesRef.current.includes(key)) {
|
|
401
|
+
setAttachedFiles(prev => [...prev, key]);
|
|
402
|
+
}
|
|
497
403
|
return;
|
|
498
404
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
}, [attachedFiles, imageUpload]);
|
|
405
|
+
await imageUploadRef.current.handleDrop(e);
|
|
406
|
+
}, []);
|
|
502
407
|
|
|
503
|
-
/** Handle paste — intercept images before normal text paste */
|
|
504
408
|
const handlePaste = useCallback((e: React.ClipboardEvent) => {
|
|
505
409
|
const items = e.clipboardData?.items;
|
|
506
410
|
if (!items) return;
|
|
507
|
-
// Check synchronously for image items — must preventDefault before awaiting
|
|
508
411
|
const hasImageItem = Array.from(items).some(
|
|
509
412
|
item => item.kind === 'file' && item.type.startsWith('image/')
|
|
510
413
|
);
|
|
511
414
|
if (hasImageItem) {
|
|
512
415
|
e.preventDefault();
|
|
513
|
-
void
|
|
416
|
+
void imageUploadRef.current.handlePaste(e);
|
|
514
417
|
}
|
|
515
|
-
}, [
|
|
418
|
+
}, []);
|
|
516
419
|
|
|
517
420
|
const handleLoadSession = useCallback((id: string) => {
|
|
518
|
-
|
|
421
|
+
sessionRef.current.loadSession(id);
|
|
519
422
|
setShowHistory(false);
|
|
520
423
|
setInput('');
|
|
521
424
|
setAttachedFiles(currentFile ? [currentFile] : []);
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
425
|
+
uploadRef.current.clearAttachments();
|
|
426
|
+
imageUploadRef.current.clearImages();
|
|
427
|
+
mentionRef.current.resetMention();
|
|
428
|
+
slashRef.current.resetSlash();
|
|
526
429
|
setSelectedSkill(null);
|
|
527
430
|
setSelectedAcpAgent(null);
|
|
528
431
|
setTimeout(() => inputRef.current?.focus(), 0);
|
|
529
|
-
}, [
|
|
432
|
+
}, [currentFile]);
|
|
530
433
|
|
|
531
|
-
const
|
|
434
|
+
const toggleHistory = useCallback(() => setShowHistory(v => !v), []);
|
|
532
435
|
const inputIconSize = 15;
|
|
436
|
+
const messageLabels = useMemo(() => ({
|
|
437
|
+
connecting: t.ask.connecting,
|
|
438
|
+
thinking: t.ask.thinking,
|
|
439
|
+
generating: t.ask.generating,
|
|
440
|
+
reconnecting: reconnectAttempt > 0 ? t.ask.reconnecting(reconnectAttempt, reconnectMaxRef.current) : undefined,
|
|
441
|
+
}), [t, reconnectAttempt]);
|
|
533
442
|
|
|
534
443
|
return (
|
|
535
444
|
<>
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
{
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
<button type="button" onClick={(e) => { e.stopPropagation(); setShowHistory(v => !v); }} aria-pressed={showHistory} className={`p-2 rounded transition-colors ${showHistory ? 'bg-muted text-foreground' : 'text-muted-foreground hover:text-foreground hover:bg-muted'}`} title={t.hints.sessionHistory}>
|
|
549
|
-
<History size={iconSize} />
|
|
550
|
-
</button>
|
|
551
|
-
<button type="button" onClick={(e) => { e.stopPropagation(); handleResetSession(); }} disabled={isLoading} className="p-2 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-40" title={t.hints.newSession}>
|
|
552
|
-
<SquarePen size={iconSize} />
|
|
553
|
-
</button>
|
|
554
|
-
{isPanel && onMaximize && (
|
|
555
|
-
<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}>
|
|
556
|
-
{maximized ? <Minimize2 size={iconSize} /> : <Maximize2 size={iconSize} />}
|
|
557
|
-
</button>
|
|
558
|
-
)}
|
|
559
|
-
{onModeSwitch && (
|
|
560
|
-
<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}>
|
|
561
|
-
{askMode === 'popup' ? <PanelRight size={iconSize} /> : <AppWindow size={iconSize} />}
|
|
562
|
-
</button>
|
|
563
|
-
)}
|
|
564
|
-
{onClose && (
|
|
565
|
-
<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">
|
|
566
|
-
<X size={isPanel ? iconSize : 15} />
|
|
567
|
-
</button>
|
|
568
|
-
)}
|
|
569
|
-
</div>
|
|
570
|
-
</div>
|
|
445
|
+
<AskHeader
|
|
446
|
+
isPanel={isPanel}
|
|
447
|
+
showHistory={showHistory}
|
|
448
|
+
onToggleHistory={toggleHistory}
|
|
449
|
+
onReset={handleResetSession}
|
|
450
|
+
isLoading={isLoading}
|
|
451
|
+
maximized={maximized}
|
|
452
|
+
onMaximize={onMaximize}
|
|
453
|
+
askMode={askMode}
|
|
454
|
+
onModeSwitch={onModeSwitch}
|
|
455
|
+
onClose={onClose}
|
|
456
|
+
/>
|
|
571
457
|
|
|
572
458
|
{/* Session tabs — panel variant only */}
|
|
573
459
|
{isPanel && session.sessions.length > 0 && (
|
|
@@ -586,12 +472,14 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
586
472
|
activeSessionId={session.activeSessionId}
|
|
587
473
|
onLoad={handleLoadSession}
|
|
588
474
|
onDelete={session.deleteSession}
|
|
475
|
+
onRename={session.renameSession}
|
|
589
476
|
onClearAll={session.clearAllSessions}
|
|
590
477
|
labels={{
|
|
591
478
|
title: t.ask.sessionHistory ?? 'Session History',
|
|
592
479
|
clearAll: t.ask.clearAll ?? 'Clear all',
|
|
593
480
|
confirmClear: t.ask.confirmClear ?? 'Confirm clear?',
|
|
594
481
|
noSessions: t.ask.noSessions ?? 'No saved sessions.',
|
|
482
|
+
rename: t.ask.renameSession ?? 'Rename',
|
|
595
483
|
}}
|
|
596
484
|
/>
|
|
597
485
|
)}
|
|
@@ -602,14 +490,10 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
602
490
|
isLoading={isLoading}
|
|
603
491
|
loadingPhase={loadingPhase}
|
|
604
492
|
emptyPrompt={t.ask.emptyPrompt}
|
|
493
|
+
emptyHint={t.ask.emptyHint}
|
|
605
494
|
suggestions={t.ask.suggestions}
|
|
606
495
|
onSuggestionClick={setInput}
|
|
607
|
-
labels={
|
|
608
|
-
connecting: t.ask.connecting,
|
|
609
|
-
thinking: t.ask.thinking,
|
|
610
|
-
generating: t.ask.generating,
|
|
611
|
-
reconnecting: reconnectAttempt > 0 ? t.ask.reconnecting(reconnectAttempt, reconnectMaxRef.current) : undefined,
|
|
612
|
-
}}
|
|
496
|
+
labels={messageLabels}
|
|
613
497
|
/>
|
|
614
498
|
|
|
615
499
|
{/* Popovers — flex children so they stay within overflow boundary (absolute positioning would be clipped by RightAskPanel's overflow-hidden) */}
|
|
@@ -635,196 +519,158 @@ export default function AskContent({ visible, currentFile, initialMessage, initi
|
|
|
635
519
|
</div>
|
|
636
520
|
)}
|
|
637
521
|
|
|
638
|
-
{/*
|
|
639
|
-
<div
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
522
|
+
{/* Composer card — unified input area with rounded container */}
|
|
523
|
+
<div className="shrink-0 px-3 pb-2 pt-1">
|
|
524
|
+
<div
|
|
525
|
+
className={cn(
|
|
526
|
+
'rounded-xl border border-border/60 bg-card shadow-sm transition-shadow',
|
|
527
|
+
isDragOver && 'ring-2 ring-[var(--amber)] bg-[var(--amber-dim)]',
|
|
528
|
+
)}
|
|
529
|
+
onDragOver={handleDragOver}
|
|
530
|
+
onDragLeave={handleDragLeave}
|
|
531
|
+
onDrop={handleDrop}
|
|
532
|
+
>
|
|
533
|
+
{/* Unified context chip flow */}
|
|
534
|
+
{(attachedFiles.length > 0 || upload.localAttachments.length > 0 || imageUpload.images.length > 0 || selectedSkill || selectedAcpAgent || upload.uploadError || imageUpload.imageError) && (
|
|
535
|
+
<div className={cn('px-3 pt-2.5 pb-1', isPanel ? 'max-h-24 overflow-y-auto' : 'max-h-28 overflow-y-auto')}>
|
|
536
|
+
<div className="flex flex-wrap gap-1.5">
|
|
537
|
+
{attachedFiles.map(f => (
|
|
538
|
+
<FileChip key={f} path={f} variant="kb" onRemove={() => setAttachedFiles(prev => prev.filter(x => x !== f))} />
|
|
539
|
+
))}
|
|
540
|
+
{upload.localAttachments.map((f, idx) => (
|
|
541
|
+
<FileChip key={`up-${f.name}-${idx}`} path={f.name} variant="upload" onRemove={() => upload.removeAttachment(idx)} />
|
|
542
|
+
))}
|
|
543
|
+
{imageUpload.images.map((img, idx) => (
|
|
544
|
+
<FileChip
|
|
545
|
+
key={`img-${idx}`}
|
|
546
|
+
path={`Image ${idx + 1}`}
|
|
547
|
+
variant="image"
|
|
548
|
+
imageData={img.data}
|
|
549
|
+
imageMime={img.mimeType}
|
|
550
|
+
onRemove={() => imageUpload.removeImage(idx)}
|
|
551
|
+
/>
|
|
552
|
+
))}
|
|
553
|
+
{selectedSkill && (
|
|
554
|
+
<FileChip
|
|
555
|
+
path={selectedSkill.name}
|
|
556
|
+
variant="skill"
|
|
557
|
+
onRemove={() => { setSelectedSkill(null); inputRef.current?.focus(); }}
|
|
558
|
+
/>
|
|
559
|
+
)}
|
|
560
|
+
</div>
|
|
561
|
+
{(upload.uploadError || imageUpload.imageError) && (
|
|
562
|
+
<div className="mt-1 text-xs text-error">{upload.uploadError || imageUpload.imageError}</div>
|
|
679
563
|
)}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
564
|
+
</div>
|
|
565
|
+
)}
|
|
566
|
+
|
|
567
|
+
{/* Input form */}
|
|
568
|
+
<form
|
|
569
|
+
ref={formRef}
|
|
570
|
+
onSubmit={handleSubmit}
|
|
571
|
+
className="flex items-end gap-1 px-1.5 py-1.5"
|
|
572
|
+
>
|
|
573
|
+
{/* + attach button with mini menu */}
|
|
574
|
+
<div className="relative shrink-0">
|
|
575
|
+
<button
|
|
576
|
+
type="button"
|
|
577
|
+
onClick={() => setShowAttachMenu(v => !v)}
|
|
578
|
+
className="p-1.5 rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/60 transition-colors"
|
|
579
|
+
title={t.hints.attachFile}
|
|
580
|
+
>
|
|
581
|
+
<Plus size={inputIconSize} />
|
|
582
|
+
</button>
|
|
583
|
+
{showAttachMenu && (
|
|
584
|
+
<div className="absolute bottom-full left-0 mb-1 py-1 rounded-lg border border-border bg-card shadow-lg z-50 min-w-[140px]">
|
|
585
|
+
<button
|
|
586
|
+
type="button"
|
|
587
|
+
className="flex w-full items-center gap-2 px-3 py-1.5 text-xs hover:bg-muted transition-colors text-left"
|
|
588
|
+
onClick={() => { setShowAttachMenu(false); upload.uploadInputRef.current?.click(); }}
|
|
589
|
+
>
|
|
590
|
+
<FileText size={12} className="shrink-0 text-muted-foreground" />
|
|
591
|
+
{t.ask.attachFileLabel}
|
|
592
|
+
</button>
|
|
593
|
+
<button
|
|
594
|
+
type="button"
|
|
595
|
+
className="flex w-full items-center gap-2 px-3 py-1.5 text-xs hover:bg-muted transition-colors text-left"
|
|
596
|
+
onClick={() => { setShowAttachMenu(false); imageInputRef.current?.click(); }}
|
|
597
|
+
>
|
|
598
|
+
<ImageIcon size={12} className="shrink-0 text-muted-foreground" />
|
|
599
|
+
{t.ask.attachImageLabel}
|
|
600
|
+
</button>
|
|
601
|
+
</div>
|
|
687
602
|
)}
|
|
688
603
|
</div>
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
604
|
+
|
|
605
|
+
<input
|
|
606
|
+
ref={upload.uploadInputRef}
|
|
607
|
+
type="file"
|
|
608
|
+
className="hidden"
|
|
609
|
+
multiple
|
|
610
|
+
accept=".txt,.md,.markdown,.csv,.json,.yaml,.yml,.xml,.html,.htm,.pdf,text/plain,text/markdown,text/csv,application/json,application/pdf"
|
|
611
|
+
onChange={async (e) => {
|
|
612
|
+
const inputEl = e.currentTarget;
|
|
613
|
+
await upload.pickFiles(inputEl.files);
|
|
614
|
+
inputEl.value = '';
|
|
615
|
+
}}
|
|
616
|
+
/>
|
|
617
|
+
<input
|
|
618
|
+
ref={imageInputRef}
|
|
619
|
+
type="file"
|
|
620
|
+
className="hidden"
|
|
621
|
+
multiple
|
|
622
|
+
accept="image/png,image/jpeg,image/gif,image/webp"
|
|
623
|
+
onChange={async (e) => {
|
|
624
|
+
const inputEl = e.currentTarget;
|
|
625
|
+
await imageUpload.handleFileSelect(inputEl.files);
|
|
626
|
+
inputEl.value = '';
|
|
627
|
+
}}
|
|
704
628
|
/>
|
|
705
|
-
</div>
|
|
706
|
-
)}
|
|
707
629
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
<
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
630
|
+
<textarea
|
|
631
|
+
ref={(el) => {
|
|
632
|
+
inputRef.current = el;
|
|
633
|
+
}}
|
|
634
|
+
value={input}
|
|
635
|
+
onChange={e => handleInputChange(e.target.value, e.target.selectionStart ?? undefined)}
|
|
636
|
+
onKeyDown={handleInputKeyDown}
|
|
637
|
+
onPaste={handlePaste}
|
|
638
|
+
placeholder={t.ask.placeholder}
|
|
639
|
+
rows={1}
|
|
640
|
+
className="min-w-0 flex-1 resize-none overflow-y-hidden bg-transparent py-1.5 text-sm leading-snug text-foreground placeholder:text-muted-foreground outline-none focus-visible:ring-0"
|
|
641
|
+
/>
|
|
642
|
+
|
|
643
|
+
{isLoading ? (
|
|
644
|
+
<button type="button" onClick={handleStop} className="p-1.5 rounded-lg transition-colors shrink-0 text-muted-foreground hover:text-foreground hover:bg-muted/60" title={loadingPhase === 'reconnecting' ? t.ask.cancelReconnect : t.ask.stopTitle}>
|
|
645
|
+
{loadingPhase === 'reconnecting' ? <X size={inputIconSize} /> : <StopCircle size={inputIconSize} />}
|
|
646
|
+
</button>
|
|
647
|
+
) : (
|
|
648
|
+
<button type="submit" disabled={!input.trim() && imageUpload.images.length === 0} className="p-1.5 rounded-lg disabled:opacity-40 disabled:cursor-not-allowed transition-opacity shrink-0 bg-[var(--amber)] text-[var(--amber-foreground)]">
|
|
649
|
+
<Send size={14} />
|
|
650
|
+
</button>
|
|
651
|
+
)}
|
|
652
|
+
</form>
|
|
653
|
+
|
|
654
|
+
{/* Mode + Agent + Provider selector row — inside card bottom */}
|
|
655
|
+
<div className="flex items-center gap-1.5 px-3 pb-2 pt-0.5 border-t border-border/30">
|
|
656
|
+
<ModeCapsule mode={chatMode} onChange={setChatMode} disabled={isLoading} />
|
|
657
|
+
{mounted && acpDetection.installedAgents.length > 0 && (
|
|
658
|
+
<AgentSelectorCapsule
|
|
659
|
+
selectedAgent={selectedAcpAgent}
|
|
660
|
+
onSelect={setSelectedAcpAgent}
|
|
661
|
+
installedAgents={acpDetection.installedAgents}
|
|
662
|
+
loading={acpDetection.loading}
|
|
663
|
+
/>
|
|
664
|
+
)}
|
|
665
|
+
{mounted && (
|
|
666
|
+
<ProviderModelCapsule
|
|
667
|
+
value={providerOverride}
|
|
668
|
+
onChange={setProviderOverride}
|
|
669
|
+
disabled={isLoading}
|
|
670
|
+
/>
|
|
741
671
|
)}
|
|
742
672
|
</div>
|
|
743
|
-
|
|
744
|
-
<input
|
|
745
|
-
ref={upload.uploadInputRef}
|
|
746
|
-
type="file"
|
|
747
|
-
className="hidden"
|
|
748
|
-
multiple
|
|
749
|
-
accept=".txt,.md,.markdown,.csv,.json,.yaml,.yml,.xml,.html,.htm,.pdf,text/plain,text/markdown,text/csv,application/json,application/pdf"
|
|
750
|
-
onChange={async (e) => {
|
|
751
|
-
const inputEl = e.currentTarget;
|
|
752
|
-
await upload.pickFiles(inputEl.files);
|
|
753
|
-
inputEl.value = '';
|
|
754
|
-
}}
|
|
755
|
-
/>
|
|
756
|
-
<input
|
|
757
|
-
ref={imageInputRef}
|
|
758
|
-
type="file"
|
|
759
|
-
className="hidden"
|
|
760
|
-
multiple
|
|
761
|
-
accept="image/png,image/jpeg,image/gif,image/webp"
|
|
762
|
-
onChange={async (e) => {
|
|
763
|
-
const inputEl = e.currentTarget;
|
|
764
|
-
await imageUpload.handleFileSelect(inputEl.files);
|
|
765
|
-
inputEl.value = '';
|
|
766
|
-
}}
|
|
767
|
-
/>
|
|
768
|
-
|
|
769
|
-
<textarea
|
|
770
|
-
ref={(el) => {
|
|
771
|
-
inputRef.current = el;
|
|
772
|
-
}}
|
|
773
|
-
value={input}
|
|
774
|
-
onChange={e => handleInputChange(e.target.value, e.target.selectionStart ?? undefined)}
|
|
775
|
-
onKeyDown={handleInputKeyDown}
|
|
776
|
-
onPaste={handlePaste}
|
|
777
|
-
placeholder={t.ask.placeholder}
|
|
778
|
-
rows={1}
|
|
779
|
-
className="min-w-0 flex-1 resize-none overflow-y-hidden bg-transparent py-1.5 text-sm leading-snug text-foreground placeholder:text-muted-foreground outline-none focus-visible:ring-0"
|
|
780
|
-
/>
|
|
781
|
-
|
|
782
|
-
{isLoading ? (
|
|
783
|
-
<button type="button" onClick={handleStop} className="p-1.5 rounded-md transition-colors shrink-0 text-muted-foreground hover:text-foreground hover:bg-muted" title={loadingPhase === 'reconnecting' ? t.ask.cancelReconnect : t.ask.stopTitle}>
|
|
784
|
-
{loadingPhase === 'reconnecting' ? <X size={inputIconSize} /> : <StopCircle size={inputIconSize} />}
|
|
785
|
-
</button>
|
|
786
|
-
) : (
|
|
787
|
-
<button type="submit" disabled={!input.trim() && imageUpload.images.length === 0} className="p-1.5 rounded-md disabled:opacity-40 disabled:cursor-not-allowed transition-opacity shrink-0 bg-[var(--amber)] text-[var(--amber-foreground)]">
|
|
788
|
-
<Send size={14} />
|
|
789
|
-
</button>
|
|
790
|
-
)}
|
|
791
|
-
</form>
|
|
792
|
-
</div>
|
|
793
|
-
|
|
794
|
-
{/* Footer hints — panel: compact 3 items; modal: full set */}
|
|
795
|
-
<div
|
|
796
|
-
className={cn(
|
|
797
|
-
'flex shrink-0 items-center flex-wrap px-3 pb-1.5',
|
|
798
|
-
isPanel
|
|
799
|
-
? 'gap-x-3 gap-y-1 text-[10px] text-muted-foreground/40'
|
|
800
|
-
: 'gap-x-3 gap-y-1 text-[10px] md:text-xs text-muted-foreground/50',
|
|
801
|
-
)}
|
|
802
|
-
>
|
|
803
|
-
<span suppressHydrationWarning>
|
|
804
|
-
<kbd className="font-mono">↵</kbd> {t.ask.send}
|
|
805
|
-
</span>
|
|
806
|
-
{!isPanel && (
|
|
807
|
-
<span suppressHydrationWarning>
|
|
808
|
-
<kbd className="font-mono">⇧</kbd>
|
|
809
|
-
<kbd className="font-mono ml-0.5">↵</kbd> {t.ask.newlineHint}
|
|
810
|
-
</span>
|
|
811
|
-
)}
|
|
812
|
-
<span suppressHydrationWarning>
|
|
813
|
-
<kbd className="font-mono">@</kbd> {t.ask.attachFile}
|
|
814
|
-
</span>
|
|
815
|
-
<span suppressHydrationWarning>
|
|
816
|
-
<kbd className="font-mono">/</kbd> {t.ask.skillsHint}
|
|
817
|
-
</span>
|
|
818
|
-
{!isPanel && (
|
|
819
|
-
<span suppressHydrationWarning>
|
|
820
|
-
<kbd className="font-mono">ESC</kbd> {t.search.close}
|
|
821
|
-
</span>
|
|
822
|
-
)}
|
|
823
|
-
{isLoading && input.trim() && (
|
|
824
|
-
<span className="text-[10px] text-[var(--amber)]/80">
|
|
825
|
-
{t.ask.draftingHint}
|
|
826
|
-
</span>
|
|
827
|
-
)}
|
|
673
|
+
</div>
|
|
828
674
|
</div>
|
|
829
675
|
</>
|
|
830
676
|
);
|