-
{tool.title}
-
- {tool.description}
+ {tools.map((tool) => {
+ // 终端卡片在有多个 shell 时是分裂按钮:主区开默认 shell,右缘
+ // 箭头展开 shell 选择菜单(能力与原「+」菜单的子菜单一致)。
+ const splitShellMenu = tool.key === "terminal" && shellOptions.length > 1;
+ const card = (
+
+ );
+ if (!splitShellMenu) {
+ return
{card}
;
+ }
+ return (
+
+ {card}
+
+
+
+
+
+ {shellOptions.map((option) => (
+ onCreateTerminal(option.id)}
+ disabled={tool.disabled}
+ className="gap-2 text-xs"
+ title={option.command || option.label}
+ >
+
+ {option.label}
+
+ ))}
+
+
-
- ))}
+ );
+ })}
{loading ? (
{t("projectTools.loading")}
diff --git a/crates/agent-gateway/web/src/components/project-tools/RightDockPanel.tsx b/crates/agent-gateway/web/src/components/project-tools/RightDockPanel.tsx
index f137cb3a6..17a509049 100644
--- a/crates/agent-gateway/web/src/components/project-tools/RightDockPanel.tsx
+++ b/crates/agent-gateway/web/src/components/project-tools/RightDockPanel.tsx
@@ -732,7 +732,7 @@ export const RightDockPanel = memo(function RightDockPanel(props: RightDockPanel
className={cn(
"project-tools-panel zone-font-scale fixed inset-x-0 bottom-0 z-40 flex h-[min(72vh,34rem)] min-h-0 w-full shrink-0 flex-col overflow-hidden bg-background shadow-2xl transition-[opacity,transform] duration-200 ease-out motion-reduce:transition-none md:relative md:inset-auto md:z-10 md:h-full md:overflow-visible md:shadow-none",
isOpen
- ? "pointer-events-auto translate-y-0 border-t border-border opacity-100 md:w-[var(--project-tools-panel-width)] md:translate-x-0 md:border-l md:border-t-0"
+ ? "pointer-events-auto translate-y-0 border-t border-border opacity-100 md:w-[var(--project-tools-panel-width)] md:translate-x-0 md:border-t-0"
: "pointer-events-none translate-y-full border-t border-transparent opacity-0 md:translate-x-3 md:translate-y-0 md:border-l-0 md:border-t-0",
effectiveWidthCollapsed ? "md:w-0" : "md:w-[var(--project-tools-panel-width)]",
)}
@@ -749,6 +749,15 @@ export const RightDockPanel = memo(function RightDockPanel(props: RightDockPanel
{effectiveShouldRenderContent ? (
<>
+ {/* 分栏竖线:贯穿到顶,但顶端由透明渐入实色(~3rem 处),顶部
+ 条带视觉上保持连续;有头部时实色段恰好从横线处开始衔接。 */}
+
-
+ {/* 空态(启动页)不渲染头部行:「新建」按钮浮动在启动页右上角。 */}
+ {!showRightDockChooser ? (
-
+
+
+ {/* 新建按钮紧跟最后一个标签(浏览器标签栏式) */}
+
+
+
+
+
-
+ {onClose ? (
+
+ ) : null}
-
- {onClose ? (
-
- ) : null}
-
+ ) : null}
{pendingCloseSession ? (
@@ -862,19 +880,35 @@ export const RightDockPanel = memo(function RightDockPanel(props: RightDockPanel
{disabledMessage}
) : showRightDockChooser ? (
-
+
+ {/* 桌面端不再浮动「+」——启动页卡片即完整的创建入口,终端卡
+ 片自带 shell 选择;这里只保留移动端的关闭按钮。 */}
+ {onClose ? (
+
+ ) : null}
+
+
) : (
) => {
- if (event.button !== 0 || event.detail !== 1) {
- return;
- }
- void getAppWindow()
- .startDragging()
- .catch((error) => reportWindowChromeError("drag", error));
- },
- [getAppWindow],
- );
+ // 悬浮胶囊会盖住窗口右上角:把预留宽度暴露成全局 CSS 变量,各视图的
+ // 顶右头部(ChatHeader / 右侧面板 / 编辑器覆盖层)据此加内边距让位。
+ useEffect(() => {
+ if (!isVisible || typeof document === "undefined") {
+ return undefined;
+ }
+ const root = document.documentElement;
+ root.style.setProperty("--win-chrome-reserve", "128px");
+ return () => {
+ root.style.removeProperty("--win-chrome-reserve");
+ };
+ }, [isVisible]);
const toggleMaximize = useCallback(() => {
const appWindow = getAppWindow();
@@ -143,16 +143,6 @@ export function WindowsTitleBar() {
.catch((error) => reportWindowChromeError("toggle maximized state for", error));
}, [getAppWindow]);
- const handleTitleDoubleClick = useCallback(
- (event: MouseEvent) => {
- if (event.button !== 0) {
- return;
- }
- toggleMaximize();
- },
- [toggleMaximize],
- );
-
const minimizeWindow = useCallback(() => {
void getAppWindow()
.minimize()
@@ -172,36 +162,25 @@ export function WindowsTitleBar() {
const maximizeLabel = isMaximized ? t("window.restore") : t("window.maximize");
return (
-
-
-

-
- {t("app.name")}
-
-
+ <>
+ {/* 顶缘拖拽热区:内容顶到窗顶后,这 6px 承担拖拽与双击最大化
+ (data-tauri-drag-region 由 Tauri 核心处理,二者内建)。 */}
+
-
-
+
+ >
);
}
diff --git a/crates/agent-gui/src/components/project-tools/RightDockLauncher.tsx b/crates/agent-gui/src/components/project-tools/RightDockLauncher.tsx
index b4c1d6759..b3f3ba65a 100644
--- a/crates/agent-gui/src/components/project-tools/RightDockLauncher.tsx
+++ b/crates/agent-gui/src/components/project-tools/RightDockLauncher.tsx
@@ -1,7 +1,7 @@
import { useLocale } from "../../i18n";
import { cn } from "../../lib/shared/utils";
import type { TerminalShellOption } from "../../lib/terminal/types";
-import { ChevronRight, Cpu, Plus, Terminal } from "../icons";
+import { ChevronDown, ChevronRight, Cpu, Plus, Terminal } from "../icons";
import { buttonVariants } from "../ui/button";
import {
DropdownMenu,
@@ -34,6 +34,7 @@ type RightDockCreateMenuProps = RightDockLauncherActions & {
};
type RightDockChooserProps = RightDockLauncherActions & {
+ shellOptions: TerminalShellOption[];
terminalReady: boolean;
terminalDisabledMessage?: string;
disabledMessage?: string;
@@ -105,7 +106,7 @@ export function RightDockCreateMenu(props: RightDockCreateMenuProps) {
title={t("projectTools.newProjectTool")}
className={cn(
buttonVariants({ variant: "ghost", size: "icon" }),
- "h-8 w-8 rounded-lg text-muted-foreground hover:text-foreground",
+ "h-7 w-7 rounded-md text-muted-foreground/80 hover:text-foreground",
)}
>