authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-17 16:09:05-08:00
committergravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-17 16:09:09-08:00
logba4a62eb0335805b6aeab55d55836a2dfbb6d5b5
treef825e5add29f0d72998d826c17bd3a284e584139
parent09ac18db8204e0057a6cf0f73424e4345f2070ab

fmt


5 files changed, 50 insertions(+), 39 deletions(-)

apps/web/src/chat-scroll.test.ts+1-4
......@@ -1,9 +1,6 @@
11import { describe, expect, it } from "vitest";
22
3import {
4 AUTO_SCROLL_BOTTOM_THRESHOLD_PX,
5 isScrollContainerNearBottom,
6} from "./chat-scroll";
3import { AUTO_SCROLL_BOTTOM_THRESHOLD_PX, isScrollContainerNearBottom } from "./chat-scroll";
74
85describe("isScrollContainerNearBottom", () => {
96 it("returns true when already at bottom", () => {
apps/web/src/components/ChatView.tsx+3-1
......@@ -1447,7 +1447,9 @@ const MessagesTimeline = memo(function MessagesTimeline({
14471447 if (!hasMessages && !isWorking) {
14481448 return (
14491449 <div className="flex h-full items-center justify-center">
1450 <p className="text-sm text-muted-foreground/30">Send a message to start the conversation.</p>
1450 <p className="text-sm text-muted-foreground/30">
1451 Send a message to start the conversation.
1452 </p>
14511453 </div>
14521454 );
14531455 }
apps/web/src/components/GitActionsControl.tsx+2-1
......@@ -627,7 +627,8 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
627627 : gitStatusForActions.aheadCount === 0 &&
628628 gitStatusForActions.behindCount === 0
629629 ? "Up to date"
630 : gitStatusForActions.aheadCount > 0 && gitStatusForActions.behindCount > 0
630 : gitStatusForActions.aheadCount > 0 &&
631 gitStatusForActions.behindCount > 0
631632 ? `Diverged (+${gitStatusForActions.aheadCount} / -${gitStatusForActions.behindCount})`
632633 : gitStatusForActions.aheadCount > 0
633634 ? `Ahead by ${gitStatusForActions.aheadCount}`
apps/web/src/keybindings.test.ts+27-20
......@@ -98,7 +98,9 @@ const DEFAULT_BINDINGS = compile([
9898describe("isTerminalToggleShortcut", () => {
9999 it("matches Cmd+J on macOS", () => {
100100 assert.isTrue(
101 isTerminalToggleShortcut(event({ metaKey: true }), DEFAULT_BINDINGS, { platform: "MacIntel" }),
101 isTerminalToggleShortcut(event({ metaKey: true }), DEFAULT_BINDINGS, {
102 platform: "MacIntel",
103 }),
102104 );
103105 });
104106
......@@ -219,7 +221,10 @@ describe("shortcutLabelForCommand", () => {
219221 whenAst: whenNot(whenIdentifier("terminalFocus")),
220222 },
221223 ]);
222 assert.strictEqual(shortcutLabelForCommand(bindings, "terminal.split", "Linux"), "Ctrl+Shift+\\");
224 assert.strictEqual(
225 shortcutLabelForCommand(bindings, "terminal.split", "Linux"),
226 "Ctrl+Shift+\\",
227 );
223228 });
224229
225230 it("returns labels for non-terminal commands", () => {
......@@ -247,22 +252,14 @@ describe("chat/editor shortcuts", () => {
247252
248253 it("matches chat.newLocal shortcut", () => {
249254 assert.isTrue(
250 isChatNewLocalShortcut(
251 event({ key: "n", metaKey: true, shiftKey: true }),
252 DEFAULT_BINDINGS,
253 {
254 platform: "MacIntel",
255 },
256 ),
255 isChatNewLocalShortcut(event({ key: "n", metaKey: true, shiftKey: true }), DEFAULT_BINDINGS, {
256 platform: "MacIntel",
257 }),
257258 );
258259 assert.isTrue(
259 isChatNewLocalShortcut(
260 event({ key: "n", ctrlKey: true, shiftKey: true }),
261 DEFAULT_BINDINGS,
262 {
263 platform: "Linux",
264 },
265 ),
260 isChatNewLocalShortcut(event({ key: "n", ctrlKey: true, shiftKey: true }), DEFAULT_BINDINGS, {
261 platform: "Linux",
262 }),
266263 );
267264 });
268265
......@@ -344,11 +341,17 @@ describe("cross-command precedence", () => {
344341
345342describe("formatShortcutLabel", () => {
346343 it("formats labels for macOS", () => {
347 assert.strictEqual(formatShortcutLabel(modShortcut("d", { shiftKey: true }), "MacIntel"), "⇧⌘D");
344 assert.strictEqual(
345 formatShortcutLabel(modShortcut("d", { shiftKey: true }), "MacIntel"),
346 "⇧⌘D",
347 );
348348 });
349349
350350 it("formats labels for non-macOS", () => {
351 assert.strictEqual(formatShortcutLabel(modShortcut("d", { shiftKey: true }), "Linux"), "Ctrl+Shift+D");
351 assert.strictEqual(
352 formatShortcutLabel(modShortcut("d", { shiftKey: true }), "Linux"),
353 "Ctrl+Shift+D",
354 );
352355 });
353356
354357 it("formats labels for plus key", () => {
......@@ -368,7 +371,9 @@ describe("isTerminalClearShortcut", () => {
368371 });
369372
370373 it("ignores non-keydown events", () => {
371 assert.isFalse(isTerminalClearShortcut(event({ type: "keyup", key: "l", ctrlKey: true }), "Linux"));
374 assert.isFalse(
375 isTerminalClearShortcut(event({ type: "keyup", key: "l", ctrlKey: true }), "Linux"),
376 );
372377 });
373378});
374379
......@@ -413,7 +418,9 @@ describe("terminalNavigationShortcutData", () => {
413418 "MacIntel",
414419 ),
415420 );
416 assert.isNull(terminalNavigationShortcutData(event({ key: "ArrowLeft", metaKey: true }), "Linux"));
421 assert.isNull(
422 terminalNavigationShortcutData(event({ key: "ArrowLeft", metaKey: true }), "Linux"),
423 );
417424 assert.isNull(terminalNavigationShortcutData(event({ key: "a", altKey: true }), "MacIntel"));
418425 });
419426
packages/contracts/src/keybindings.ts+17-13
......@@ -21,14 +21,16 @@ export const keybindingRuleSchema = z.object({
2121
2222export const keybindingsConfigSchema = z.array(keybindingRuleSchema).max(256);
2323
24export const keybindingShortcutSchema = z.object({
25 key: z.string().trim().min(1).max(32),
26 metaKey: z.boolean(),
27 ctrlKey: z.boolean(),
28 shiftKey: z.boolean(),
29 altKey: z.boolean(),
30 modKey: z.boolean(),
31}).strict();
24export const keybindingShortcutSchema = z
25 .object({
26 key: z.string().trim().min(1).max(32),
27 metaKey: z.boolean(),
28 ctrlKey: z.boolean(),
29 shiftKey: z.boolean(),
30 altKey: z.boolean(),
31 modKey: z.boolean(),
32 })
33 .strict();
3234
3335export type KeybindingWhenNode =
3436 | { type: "identifier"; name: string }
......@@ -59,11 +61,13 @@ export const keybindingWhenNodeSchema: z.ZodType<KeybindingWhenNode> = z.lazy(()
5961 ]),
6062);
6163
62export const resolvedKeybindingRuleSchema = z.object({
63 command: keybindingCommandSchema,
64 shortcut: keybindingShortcutSchema,
65 whenAst: keybindingWhenNodeSchema.optional(),
66}).strict();
64export const resolvedKeybindingRuleSchema = z
65 .object({
66 command: keybindingCommandSchema,
67 shortcut: keybindingShortcutSchema,
68 whenAst: keybindingWhenNodeSchema.optional(),
69 })
70 .strict();
6771
6872export const resolvedKeybindingsConfigSchema = z.array(resolvedKeybindingRuleSchema).max(256);
6973