From 7821a8a8af73bbb6e9152e5910cf6a2e6899eb4b Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Fri, 6 Mar 2026 22:53:03 +0700 Subject: [PATCH] feat(app): add Mod+W close-tab shortcut for desktop, simplify Android build scripts, and use universal DMG download --- CLAUDE.md | 10 ++++--- package.json | 4 +-- packages/app/package.json | 6 ++--- .../src/keyboard/keyboard-shortcuts.test.ts | 26 +++++++++++++++++-- .../app/src/keyboard/keyboard-shortcuts.ts | 22 ++++++++++++++-- packages/website/src/routes/index.tsx | 2 +- 6 files changed, 57 insertions(+), 13 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 994c9a174..5038894c9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -141,12 +141,15 @@ From `packages/app`: ```bash # development (debug) -APP_VARIANT=development npx expo prebuild --platform android --clean --non-interactive +APP_VARIANT=development npx expo prebuild --platform android --non-interactive APP_VARIANT=development npx expo run:android --variant=debug # production (release) -APP_VARIANT=production npx expo prebuild --platform android --clean --non-interactive +APP_VARIANT=production npx expo prebuild --platform android --non-interactive APP_VARIANT=production npx expo run:android --variant=release + +# clean native project (when needed) +npx expo prebuild --platform android --clean --non-interactive ``` From repo root: @@ -154,9 +157,10 @@ From repo root: ```bash npm run android:development npm run android:production +npm run android:clean ``` -`npm run android:prod` and `npm run android:release` are aliases for `npm run android:production`. +`npm run android:release` is an alias for `npm run android:production`. ### Cloud build + submit (EAS Workflows) diff --git a/package.json b/package.json index 9384d0ca5..7b712cfa8 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,9 @@ "start": "npm run start --workspace=@getpaseo/server", "android": "npm run android --workspace=@getpaseo/app", "android:development": "npm run android:development --workspace=@getpaseo/app", - "android:prod": "npm run android:prod --workspace=@getpaseo/app", "android:production": "npm run android:production --workspace=@getpaseo/app", - "android:release": "npm run android:prod --workspace=@getpaseo/app", + "android:release": "npm run android:production --workspace=@getpaseo/app", + "android:clean": "npm run android:clean --workspace=@getpaseo/app", "ios": "npm run ios --workspace=@getpaseo/app", "web": "npm run web --workspace=@getpaseo/app", "dev:desktop": "npm run dev --workspace=@getpaseo/desktop", diff --git a/packages/app/package.json b/packages/app/package.json index 08ffe4db2..d9b06564b 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -7,10 +7,10 @@ "start": "expo start", "reset-project": "node ./scripts/reset-project.js", "android": "npm run android:development", - "android:development": "APP_VARIANT=development expo prebuild --platform android --clean --non-interactive && APP_VARIANT=development expo run:android --variant=debug", - "android:production": "APP_VARIANT=production expo prebuild --platform android --clean --non-interactive && APP_VARIANT=production expo run:android --variant=release", - "android:prod": "npm run android:production", + "android:development": "APP_VARIANT=development expo prebuild --platform android --non-interactive && APP_VARIANT=development expo run:android --variant=debug", + "android:production": "APP_VARIANT=production expo prebuild --platform android --non-interactive && APP_VARIANT=production expo run:android --variant=release", "android:release": "npm run android:production", + "android:clean": "expo prebuild --platform android --clean --non-interactive", "ios": "expo run:ios", "ios:release": "expo run:ios --configuration Release", "web": "expo start --web", diff --git a/packages/app/src/keyboard/keyboard-shortcuts.test.ts b/packages/app/src/keyboard/keyboard-shortcuts.test.ts index 18c987076..f9af3a86e 100644 --- a/packages/app/src/keyboard/keyboard-shortcuts.test.ts +++ b/packages/app/src/keyboard/keyboard-shortcuts.test.ts @@ -200,7 +200,7 @@ describe("keyboard-shortcuts", () => { expect(match?.action).toBe("workspace.tab.new"); }); - it("matches Alt+Shift+W to close current tab", () => { + it("matches Alt+Shift+W to close current tab on web", () => { const match = resolveKeyboardShortcut({ event: keyboardEvent({ key: "W", @@ -208,7 +208,20 @@ describe("keyboard-shortcuts", () => { altKey: true, shiftKey: true, }), - context: shortcutContext(), + context: shortcutContext({ isTauri: false }), + }); + + expect(match?.action).toBe("workspace.tab.close.current"); + }); + + it("matches Mod+W to close current tab on tauri", () => { + const match = resolveKeyboardShortcut({ + event: keyboardEvent({ + key: "w", + code: "KeyW", + metaKey: true, + }), + context: shortcutContext({ isMac: true, isTauri: true }), }); expect(match?.action).toBe("workspace.tab.close.current"); @@ -348,6 +361,11 @@ describe("keyboard-shortcut help sections", () => { "shift", "1-9", ]); + expect(findRow(sections, "workspace-tab-close-current")?.keys).toEqual([ + "alt", + "shift", + "W", + ]); }); it("uses tauri defaults for workspace and tab jump", () => { @@ -359,6 +377,10 @@ describe("keyboard-shortcut help sections", () => { expect(findRow(sections, "new-agent")?.keys).toEqual(["mod", "shift", "O"]); expect(findRow(sections, "workspace-jump-index")?.keys).toEqual(["mod", "1-9"]); expect(findRow(sections, "workspace-tab-jump-index")?.keys).toEqual(["alt", "1-9"]); + expect(findRow(sections, "workspace-tab-close-current")?.keys).toEqual([ + "mod", + "W", + ]); }); it("uses mod+period as non-mac left sidebar shortcut", () => { diff --git a/packages/app/src/keyboard/keyboard-shortcuts.ts b/packages/app/src/keyboard/keyboard-shortcuts.ts index 72c8c6826..253a2666e 100644 --- a/packages/app/src/keyboard/keyboard-shortcuts.ts +++ b/packages/app/src/keyboard/keyboard-shortcuts.ts @@ -155,7 +155,24 @@ const SHORTCUT_BINDINGS: readonly KeyboardShortcutBinding[] = [ }, }, { - id: "workspace-tab-close-current-alt-shift-w", + id: "workspace-tab-close-current-mod-w-tauri", + action: "workspace.tab.close.current", + matches: (event) => + isMod(event) && + !event.altKey && + !event.shiftKey && + (event.code === "KeyW" || event.key.toLowerCase() === "w"), + when: (context) => context.isTauri && !context.commandCenterOpen, + help: { + id: "workspace-tab-close-current", + section: "global", + label: "Close current tab", + keys: ["mod", "W"], + when: (context) => context.isTauri, + }, + }, + { + id: "workspace-tab-close-current-alt-shift-w-web", action: "workspace.tab.close.current", matches: (event) => !event.metaKey && @@ -163,12 +180,13 @@ const SHORTCUT_BINDINGS: readonly KeyboardShortcutBinding[] = [ event.altKey && event.shiftKey && (event.code === "KeyW" || event.key.toLowerCase() === "w"), - when: (context) => !context.commandCenterOpen, + when: (context) => !context.isTauri && !context.commandCenterOpen, help: { id: "workspace-tab-close-current", section: "global", label: "Close current tab", keys: ["alt", "shift", "W"], + when: (context) => !context.isTauri, }, }, { diff --git a/packages/website/src/routes/index.tsx b/packages/website/src/routes/index.tsx index 45c9718a7..d97cdf1e0 100644 --- a/packages/website/src/routes/index.tsx +++ b/packages/website/src/routes/index.tsx @@ -5,7 +5,7 @@ import websitePackage from '../../package.json' import '~/styles.css' const desktopVersion = websitePackage.version -const macDownloadHref = `https://github.com/getpaseo/paseo/releases/download/v${desktopVersion}/Paseo_${desktopVersion}_aarch64.dmg` +const macDownloadHref = `https://github.com/getpaseo/paseo/releases/download/v${desktopVersion}/Paseo_${desktopVersion}_universal.dmg` export const Route = createFileRoute('/')({ head: () => ({