Files
paseo/packages/app/src/command-center/workspace-contributions.ts
T
Mohamed BoudraandGitHub fb9f7fb98a Make the command center stable and workspace-aware (#2749)
* feat(app): expand command center actions

Keep command center navigation stable by revealing only clipped rows without smooth centering. Prioritize a concise default list while making workspace, Git, pane, and creation actions searchable through the existing contribution and action-policy paths.

* test(app): search for query-only command action

Add project is intentionally absent from the unfiltered command center. Exercise the overlay flow through search before selecting it.
2026-08-01 15:38:07 +02:00

176 lines
5.1 KiB
TypeScript

import type { GitAction, GitActions } from "@/git/policy";
import type { KeyboardActionDefinition } from "@/keyboard/keyboard-action-dispatcher";
import type { ShortcutKey } from "@/utils/format-shortcut";
import type { CommandCenterContribution, CommandCenterIcon } from "./contributions";
export interface WorkspaceCommandCenterLabels {
section: string;
newAgent: string;
newTerminal: string;
newBrowser: string;
splitRight: string;
splitDown: string;
}
export interface WorkspaceCommandCenterIcons {
newAgent?: CommandCenterIcon;
newTerminal?: CommandCenterIcon;
newBrowser?: CommandCenterIcon;
splitRight?: CommandCenterIcon;
splitDown?: CommandCenterIcon;
git?(action: GitAction): CommandCenterIcon | undefined;
}
export interface WorkspaceCommandCenterShortcuts {
newAgent?: ShortcutKey[][];
newTerminal?: ShortcutKey[][];
splitRight?: ShortcutKey[][];
splitDown?: ShortcutKey[][];
archiveWorkspace?: ShortcutKey[][];
}
export interface WorkspaceCommandCenterSource {
gitActions: GitActions;
labels: WorkspaceCommandCenterLabels;
icons: WorkspaceCommandCenterIcons;
shortcuts: WorkspaceCommandCenterShortcuts;
capabilities: {
canSplitPanes: boolean;
canOpenBrowserTabs: boolean;
};
dispatch(action: KeyboardActionDefinition): void;
runGitAction(action: GitAction): void;
}
function buildGitContribution(
source: WorkspaceCommandCenterSource,
action: GitAction,
rank: number,
visibility: "always" | "query",
): CommandCenterContribution {
return {
id: `git:${action.id}`,
group: "workspace",
groupRank: -1,
rank,
keywords: [action.id, "git"],
visibility,
run: () => source.runGitAction(action),
presentation: {
kind: "action",
title: action.label,
sectionTitle: source.labels.section,
icon: source.icons.git?.(action),
shortcutKeys:
action.id === "archive-workspace" ? source.shortcuts.archiveWorkspace : undefined,
},
};
}
function buildWorkspaceAction(input: {
source: WorkspaceCommandCenterSource;
id: string;
rank: number;
title: string;
keywords: readonly string[];
icon?: CommandCenterIcon;
shortcutKeys?: ShortcutKey[][];
action: KeyboardActionDefinition;
visibility: "always" | "query";
}): CommandCenterContribution {
return {
id: input.id,
group: "workspace",
groupRank: -1,
rank: input.rank,
keywords: input.keywords,
visibility: input.visibility,
run: () => input.source.dispatch(input.action),
presentation: {
kind: "action",
title: input.title,
sectionTitle: input.source.labels.section,
icon: input.icon,
shortcutKeys: input.shortcutKeys,
},
};
}
export function buildWorkspaceCommandCenterContributions(
source: WorkspaceCommandCenterSource,
): CommandCenterContribution[] {
const contributions: CommandCenterContribution[] = [
buildWorkspaceAction({
source,
id: "tab:new-agent",
rank: 0,
title: source.labels.newAgent,
keywords: ["tab", "new", "agent", "chat"],
icon: source.icons.newAgent,
shortcutKeys: source.shortcuts.newAgent,
action: { id: "workspace.tab.new", scope: "workspace" },
visibility: "always",
}),
];
const primary = source.gitActions.primary;
if (primary) contributions.push(buildGitContribution(source, primary, 1, "always"));
contributions.push(
buildWorkspaceAction({
source,
id: "tab:new-terminal",
rank: 2,
title: source.labels.newTerminal,
keywords: ["terminal", "shell", "console"],
icon: source.icons.newTerminal,
shortcutKeys: source.shortcuts.newTerminal,
action: { id: "workspace.terminal.new", scope: "workspace" },
visibility: "query",
}),
);
if (source.capabilities.canOpenBrowserTabs) {
contributions.push(
buildWorkspaceAction({
source,
id: "tab:new-browser",
rank: 3,
title: source.labels.newBrowser,
keywords: ["browser", "web", "preview"],
icon: source.icons.newBrowser,
action: { id: "workspace.browser.new", scope: "workspace" },
visibility: "query",
}),
);
}
if (source.capabilities.canSplitPanes) {
contributions.push(
buildWorkspaceAction({
source,
id: "pane:split-right",
rank: 4,
title: source.labels.splitRight,
keywords: ["split", "pane", "vertical"],
icon: source.icons.splitRight,
shortcutKeys: source.shortcuts.splitRight,
action: { id: "workspace.pane.split.right", scope: "workspace" },
visibility: "query",
}),
buildWorkspaceAction({
source,
id: "pane:split-down",
rank: 5,
title: source.labels.splitDown,
keywords: ["split", "pane", "horizontal"],
icon: source.icons.splitDown,
shortcutKeys: source.shortcuts.splitDown,
action: { id: "workspace.pane.split.down", scope: "workspace" },
visibility: "query",
}),
);
}
for (const [index, action] of source.gitActions.secondary.entries()) {
if (action.id === primary?.id) continue;
contributions.push(buildGitContribution(source, action, 10 + index, "query"));
}
return contributions;
}