authorgravatar for hussein@raoufs.meEl-Hussein Abdelraouf <hussein@raoufs.me> 2026-08-15 15:27:49+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-15 12:27:49+00:00
loge17f244e0d411422dacaa0a43669fb4e8436347d
treeeaa756c4246805c9beabef0a0d2c21b5e341af9c
parent62bb97428a1bd007f4a83cdb1fcb8bbde2cdeef3
signature Signed by PGP key B5690EEEBB952194

feat(web): make right panel maximize bindable (#5091)


8 files changed, 42 insertions(+), 7 deletions(-)

apps/server/src/keybindings.test.ts+1
......@@ -203,6 +203,7 @@ it.layer(NodeServices.layer)("keybindings", (it) => {
203203 assert.equal(defaultsByCommand.get("projectSearch.toggle"), "mod+shift+f");
204204 assert.equal(defaultsByCommand.get("sidebar.toggle"), "mod+b");
205205 assert.equal(defaultsByCommand.get("rightPanel.toggle"), "mod+alt+b");
206 assert.isFalse(defaultsByCommand.has("rightPanel.toggleMaximized"));
206207 assert.equal(defaultsByCommand.get("terminal.splitVertical"), "mod+shift+d");
207208 assert.equal(defaultsByCommand.get("modelPicker.jump.1"), "mod+1");
208209 assert.equal(defaultsByCommand.get("modelPicker.jump.9"), "mod+9");
apps/web/src/components/ChatView.tsx+8
......@@ -4739,6 +4739,13 @@ function ChatViewContent(props: ChatViewProps) {
47394739 return;
47404740 }
47414741
4742 if (command === "rightPanel.toggleMaximized") {
4743 event.preventDefault();
4744 event.stopPropagation();
4745 toggleRightPanelMaximized();
4746 return;
4747 }
4748
47424749 if (command === "terminal.split") {
47434750 event.preventDefault();
47444751 event.stopPropagation();
......@@ -4834,6 +4841,7 @@ function ChatViewContent(props: ChatViewProps) {
48344841 keybindings,
48354842 onToggleDiff,
48364843 toggleRightPanel,
4844 toggleRightPanelMaximized,
48374845 toggleTerminalVisibility,
48384846 composerRef,
48394847 ]);
apps/web/src/components/settings/KeybindingsSettings.logic.test.ts+4-2
......@@ -135,7 +135,7 @@ describe("KeybindingsSettings.logic", () => {
135135 expect(options).not.toContain("customModeActive");
136136 });
137137
138 it("builds command options from defaults and resolved project bindings", () => {
138 it("builds command options from built-in commands and resolved project bindings", () => {
139139 const options = buildKeybindingCommandOptions([
140140 {
141141 command: "script.setup-db.run",
......@@ -150,7 +150,9 @@ describe("KeybindingsSettings.logic", () => {
150150 },
151151 ] satisfies ResolvedKeybindingsConfig);
152152
153 expect(options).toEqual(expect.arrayContaining(["chat.new", "script.setup-db.run"]));
153 expect(options).toEqual(
154 expect.arrayContaining(["chat.new", "rightPanel.toggleMaximized", "script.setup-db.run"]),
155 );
154156 });
155157
156158 it("reports unknown when variables without rejecting parseable expressions", () => {
apps/web/src/components/settings/KeybindingsSettings.logic.ts+2-4
......@@ -1,4 +1,5 @@
11import {
2 STATIC_KEYBINDING_COMMANDS,
23 type KeybindingCommand,
34 type KeybindingShortcut,
45 type KeybindingWhenNode,
......@@ -255,10 +256,7 @@ export function buildWhenVariableOptions(): ReadonlyArray<WhenVariableOption> {
255256export function buildKeybindingCommandOptions(
256257 keybindings: ResolvedKeybindingsConfig,
257258): ReadonlyArray<KeybindingCommandOption> {
258 const commands = new Set<KeybindingCommand>();
259 for (const binding of DEFAULT_RESOLVED_KEYBINDINGS) {
260 commands.add(binding.command);
261 }
259 const commands = new Set<KeybindingCommand>(STATIC_KEYBINDING_COMMANDS);
262260 for (const binding of keybindings) {
263261 commands.add(binding.command);
264262 }
apps/web/src/keybindings.test.ts+16
......@@ -679,6 +679,22 @@ describe("resolveShortcutCommand", () => {
679679 );
680680 });
681681
682 it("resolves a custom right panel maximize binding", () => {
683 const keybindings = compile([
684 {
685 shortcut: modShortcut("m", { shiftKey: true }),
686 command: "rightPanel.toggleMaximized",
687 },
688 ]);
689
690 assert.strictEqual(
691 resolveShortcutCommand(event({ key: "m", metaKey: true, shiftKey: true }), keybindings, {
692 platform: "MacIntel",
693 }),
694 "rightPanel.toggleMaximized",
695 );
696 });
697
682698 it("matches bracket shortcuts using the physical key code", () => {
683699 assert.strictEqual(
684700 resolveShortcutCommand(
docs/user/keybindings.md+3
......@@ -47,6 +47,9 @@ Use **Inspect** to pick an element in the app and reveal its color token. Inspec
4747successful pick; its hover glow and badge preview the element and token that click will select.
4848**Cancel** or `Escape` exits Inspect and clears its selection and spotlight.
4949
50`rightPanel.toggleMaximized` maximizes or restores the open right panel. It has no default shortcut,
51so add one in **Settings** → **Keybindings** if you want to use it.
52
5053The command palette searches active thread titles, projects, branches, user messages, and final
5154agent responses across connected environments. Message matches show one labeled excerpt while
5255keeping the thread's project, branch, and machine context visible. Message search begins after two
packages/contracts/src/keybindings.test.ts+6
......@@ -42,6 +42,12 @@ it.effect("parses keybinding rules", () =>
4242 });
4343 assert.strictEqual(parsedRightPanelToggle.command, "rightPanel.toggle");
4444
45 const parsedRightPanelToggleMaximized = yield* decode(KeybindingRule, {
46 key: "mod+shift+m",
47 command: "rightPanel.toggleMaximized",
48 });
49 assert.strictEqual(parsedRightPanelToggleMaximized.command, "rightPanel.toggleMaximized");
50
4551 const parsedClose = yield* decode(KeybindingRule, {
4652 key: "mod+w",
4753 command: "terminal.close",
packages/contracts/src/keybindings.ts+2-1
......@@ -47,7 +47,7 @@ export const MODEL_PICKER_KEYBINDING_COMMANDS = [
4747] as const;
4848export type ModelPickerKeybindingCommand = (typeof MODEL_PICKER_KEYBINDING_COMMANDS)[number];
4949
50const STATIC_KEYBINDING_COMMANDS = [
50export const STATIC_KEYBINDING_COMMANDS = [
5151 "sidebar.toggle",
5252 "terminal.toggle",
5353 "terminal.split",
......@@ -55,6 +55,7 @@ const STATIC_KEYBINDING_COMMANDS = [
5555 "terminal.new",
5656 "terminal.close",
5757 "rightPanel.toggle",
58 "rightPanel.toggleMaximized",
5859 "diff.toggle",
5960 "preview.toggle",
6061 "preview.refresh",