Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

175 lines
4.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
agentToolPanelDefaultWidthById,
clampAgentToolPanelWidth,
createAgentToolSidebarState,
filterAgentToolAddablePanels,
filterAgentToolPanels,
reduceAgentToolSidebarState,
resolveAgentToolPanelExpansionTransfer,
shouldAutoCollapseAgentToolSidebar,
type AgentToolPanelDefinition
} from "./model.ts";
const panels: readonly AgentToolPanelDefinition[] = [
{ id: "files", label: "Files" },
{ id: "terminal", label: "Terminal" },
{ id: "browser", label: "Browser" }
];
describe("agent tool sidebar model", () => {
it("uses the shared 720px default for task and message panels", () => {
expect(agentToolPanelDefaultWidthById.tasks).toBe(720);
expect(agentToolPanelDefaultWidthById.messages).toBe(720);
});
it("preserves the established Side width bounds in the shared sidebar", () => {
expect(agentToolPanelDefaultWidthById.side).toBe(440);
expect(
clampAgentToolPanelWidth({
mainContentMinWidth: 280,
panel: "side",
viewportWidth: 1_400,
width: 100
})
).toBe(360);
expect(
clampAgentToolPanelWidth({
mainContentMinWidth: 280,
panel: "side",
viewportWidth: 1_400,
width: 900
})
).toBe(600);
});
it("keeps only unique supported panels in host order", () => {
expect(
filterAgentToolPanels([
...panels,
{ id: "files", label: "Duplicate" },
{ id: "unsupported", label: "Unsupported" }
])
).toEqual(panels);
});
it("preserves host-owned panel creation policy", () => {
const contextual = { canAdd: false, id: "side", label: "Side" } as const;
expect(filterAgentToolPanels([contextual])).toEqual([contextual]);
expect(filterAgentToolAddablePanels([...panels, contextual])).toEqual(
panels
);
});
it("reuses the latest panel tab and returns to the previous tab when closing", () => {
let state = createAgentToolSidebarState();
state = reduceAgentToolSidebarState(state, {
panel: "files",
tabId: "files:first",
type: "add-panel"
});
state = reduceAgentToolSidebarState(state, {
panel: "terminal",
tabId: "terminal:first",
type: "add-panel"
});
state = reduceAgentToolSidebarState(state, {
panel: "files",
tabId: "files:ignored",
type: "open-panel"
});
expect(state.activeTabId).toBe("files:first");
expect(state.mountedTabs).toHaveLength(2);
state = reduceAgentToolSidebarState(state, {
tabId: "files:first",
type: "close-tab"
});
expect(state.activePanel).toBe("terminal");
expect(state.activeTabId).toBe("terminal:first");
state = reduceAgentToolSidebarState(state, {
tabId: "terminal:first",
type: "close-tab"
});
expect(state.activePanel).toBeNull();
expect(state.activeTabId).toBeNull();
expect(state.mountedTabs).toEqual([]);
});
it("clamps panel width to the panel and remaining-content bounds", () => {
expect(
clampAgentToolPanelWidth({
mainContentMinWidth: 280,
panel: "files",
viewportWidth: 900,
width: 900
})
).toBe(620);
});
it("collapses a sidebar only after it crosses the main-content boundary", () => {
expect(
shouldAutoCollapseAgentToolSidebar({
containerWidth: 1470,
mainContentMinWidth: 750,
sidebarWidth: 720
})
).toBe(false);
expect(
shouldAutoCollapseAgentToolSidebar({
containerWidth: 1469,
mainContentMinWidth: 750,
sidebarWidth: 720
})
).toBe(true);
});
it("ensures a background panel without changing the active tab", () => {
let state = createAgentToolSidebarState({
activePanel: "files",
activeTabId: "files:first",
mountedTabs: [{ id: "files:first", panel: "files" }]
});
state = reduceAgentToolSidebarState(state, {
panel: "browser",
resourceId: "agent-1",
tabId: "browser:agent-1",
type: "ensure-panel"
});
expect(state.activePanel).toBe("files");
expect(state.activeTabId).toBe("files:first");
expect(state.mountedTabs).toContainEqual({
id: "browser:agent-1",
panel: "browser",
resourceId: "agent-1"
});
const repeated = reduceAgentToolSidebarState(state, {
panel: "browser",
resourceId: "agent-1",
tabId: "browser:duplicate",
type: "ensure-panel"
});
expect(repeated).toBe(state);
});
it("transfers expansion while remembering both panel widths", () => {
expect(
resolveAgentToolPanelExpansionTransfer({
expandedPanel: "files",
nextPanel: "browser",
nextPanelWidth: 640,
widthBeforeExpansion: 560
})
).toEqual({
expandedPanel: "browser",
nextPanelWidthBeforeExpansion: 640,
previousPanel: "files",
previousPanelWidth: 560
});
});
});