feat(web): prominent agent launcher (FAB, Ctrl/Cmd+J, sidebar entry, quick goals)

- Bottom-right FAB (56px, prism ring) with active-run count, pulse and latest
  status summary; turns into "collapse" beside the open drawer; hidden on the
  Agent page and while the mini dock shows; lifts above bottom floating bars
- Ctrl/Cmd+J toggles the drawer, Esc closes; input is focused on open
- Emphasized Agent entry at the top of the sidebar (expanded and collapsed)
  with active-run count; header button kept only below xl
- Drawer first screen offers 3 page-aware quick goals that fill the input
- Respects reduced motion; AgentShortcutsHelp exported for the settings page

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 02:10:28 +08:00
1 parent 16ab2a6c84
commit 39a001c099
7 files changed
+433 -8

No files matched your search

+8 -2
View File
@@ -5,6 +5,7 @@ import { Link, NavLink, Outlet, useLocation } from "react-router";
import { useSession } from "~/api/auth.ts";
import { AgentDrawer, AgentDrawerTrigger } from "~/components/agent/agent-drawer.tsx";
import { AccountMenu } from "~/components/console/account-menu.tsx";
import { AgentLauncher, AgentNavEntry } from "~/components/console/agent-launcher.tsx";
import { ErrorState } from "~/components/console/empty-state.tsx";
import { CONSOLE_BASE, findNavItem, NAV_GROUPS, NAV_ITEMS, type NavGroup } from "~/components/console/nav.ts";
import PrismLeak from "~/components/prism-leak.tsx";
@@ -54,6 +55,7 @@ function ExpandedNav({ groups, onNavigate }: { groups: NavGroup[]; onNavigate?:
style={{ transform: `translate(${pill.x}px, ${pill.y}px)`, width: pill.w, height: pill.h }}
/>
) : null}
<AgentNavEntry onNavigate={onNavigate} />
{groups.map((group) => (
<div key={group.title}>
<p className="mb-1 px-2 text-micro font-semibold tracking-[0.15em] text-muted-foreground/75 uppercase">
@@ -94,6 +96,7 @@ function ExpandedNav({ groups, onNavigate }: { groups: NavGroup[]; onNavigate?:
function CollapsedNav() {
return (
<nav className="flex flex-1 flex-col items-center gap-1 overflow-y-auto py-4">
<AgentNavEntry collapsed />
{NAV_ITEMS.map((item) => (
<NavLink
key={item.to}
@@ -223,18 +226,21 @@ function ConsoleShell({ session }: { session: SessionInfo }) {
<span className="truncate text-sm font-semibold text-foreground">{activeLabel}</span>
</div>
<div className="ml-auto flex items-center gap-2">
<AgentDrawerTrigger />
{/* 桌面有侧栏主入口与右下角悬浮按钮,顶栏小按钮只在窄屏保留 */}
<AgentDrawerTrigger className="xl:hidden" />
<ThemeToggle />
<AccountMenu session={session} />
</div>
</header>
<main className="relative flex-1 overflow-x-hidden px-4 py-6 md:px-6 md:py-8">
{/* 底部留出悬浮按钮的高度,页面末尾的内容能滚到它上面 */}
<main className="relative flex-1 overflow-x-hidden px-4 pt-6 pb-24 md:px-6 md:pt-8">
<div key={location.pathname} className="mx-auto max-w-6xl motion-safe:animate-blur-in">
<Outlet />
</div>
</main>
<AgentDrawer />
<AgentLauncher />
</div>
</div>
);