-
Notifications
You must be signed in to change notification settings - Fork 2.3k
feat(ui): bring back quick launcher #5144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
we should think about whether this is the way; message to submit & auto submit does feel like a bit of an anti pattern that will get us in trouble furhter down the lne |
|
I think the UX of: keyboard shortcut, type message and hit enter, see chat begin with that message seems ok, right @DOsinga? Are you saying anti-pattern in UX or something with the impl? @Abhijay007 I like what I see in the demo, but could you make it so the input doesn't have margins on top and bottom? It should fill the whole little window I think. |
Sure, I will do that. At first, I thought it was only in the local setup, but it might not be visible in prod, as my local electron app sometimes doesn't take all CSS elements in local, but I will update it |
|
I like it! Just a note that its integrated with basechat2 which is an in progress rewrite of how chat will work and initialize from a new message and still a ways off. Maybe it would be better to integrate this with the current basechat to get use out of it faster and then we can port it to the new way when that rewrite is closer. |
sure will fix that |
|
at the same time, track the progress, #5237 is the new way but might be a while before it lands |
Signed-off-by: Abhijay007 <[email protected]>
Signed-off-by: Abhijay007 <[email protected]>
447519d to
2a84495
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a new launcher feature that allows users to quickly open a search interface with a global keyboard shortcut (Cmd/Ctrl+Alt+Shift+G). The launcher provides a streamlined input experience to create new chat windows with initial messages without needing to open the full application.
- A new
LauncherViewcomponent creates a minimal, always-on-top window for quick queries - The global hotkey now opens the launcher instead of focusing the existing window
- Initial messages from the launcher are properly propagated to new chat windows via IPC events
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/desktop/src/renderer.tsx | Conditionally skips goosed connection setup for launcher view |
| ui/desktop/src/main.ts | Adds createLauncher function, IPC handlers, and message propagation logic |
| ui/desktop/src/components/LauncherView.tsx | New minimal search input component for quick access |
| ui/desktop/src/components/BaseChat2.tsx | Supports auto-submission of initial messages |
| ui/desktop/src/App.tsx | Registers launcher route and handles initial message IPC events |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const [searchParams, setSearchParams] = useSearchParams(); | ||
| const [initialMessage] = useState(routeState.initialMessage); | ||
|
|
||
| const initialMessage = routeState.initialMessage; |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The initialMessage is now directly assigned from routeState.initialMessage instead of being stored in state via useState. This means changes to routeState.initialMessage after the initial render won't be reflected. If the route state can change during the component's lifecycle, this could lead to stale data. Consider whether this behavior is intentional or if the original useState was necessary to preserve the value.
| const initialMessage = routeState.initialMessage; | |
| const [initialMessage] = useState(() => routeState.initialMessage); |
| e.preventDefault(); | ||
| if (query.trim()) { | ||
| // Create a new chat window with the query | ||
| const workingDir = window.appConfig?.get('GOOSE_WORKING_DIR') as string; |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workingDir is retrieved inside the handleSubmit function and cast to string, but window.appConfig?.get('GOOSE_WORKING_DIR') could return undefined or unknown. This could result in passing undefined to createChatWindow which might not handle it correctly. Consider adding a null check or providing a default value.
| const workingDir = window.appConfig?.get('GOOSE_WORKING_DIR') as string; | |
| const workingDir = (window.appConfig?.get('GOOSE_WORKING_DIR') ?? '') as string; |
| launcherWindow.setPosition( | ||
| Math.round(width / 2 - windowBounds.width / 2), | ||
| Math.round(height / 3 - windowBounds.height / 2) |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The launcher window is positioned at height / 3 vertically. This magic number (1/3) lacks explanation. Consider adding a comment explaining why this specific vertical position was chosen, or extract it as a named constant like LAUNCHER_VERTICAL_POSITION_RATIO = 1/3.
| launcherWindow.setPosition( | |
| Math.round(width / 2 - windowBounds.width / 2), | |
| Math.round(height / 3 - windowBounds.height / 2) | |
| // Position the launcher window at one-third of the screen height for optimal visibility and accessibility. | |
| const LAUNCHER_VERTICAL_POSITION_RATIO = 1 / 3; | |
| launcherWindow.setPosition( | |
| Math.round(width / 2 - windowBounds.width / 2), | |
| Math.round(height * LAUNCHER_VERTICAL_POSITION_RATIO - windowBounds.height / 2) |
|
|
||
| // Get the window that sent the react-ready event | ||
| const window = BrowserWindow.fromWebContents(event.sender); | ||
| const windowId = window?.id; |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code retrieves window from event.sender but doesn't check if it's null before accessing window.id on line 1071. Although the optional chaining on line 1071 prevents an error, if window is null, the subsequent code on lines 1074-1078 should not execute. Consider adding an early return: if (!window) return; after line 1070.
| const windowId = window?.id; | |
| if (!window) return; | |
| const windowId = window.id; |
| onChange={(e) => setQuery(e.target.value)} | ||
| onKeyDown={handleKeyDown} | ||
| className="w-full h-full bg-transparent text-text-default text-xl px-6 outline-none placeholder-text-muted" | ||
| placeholder="Ask goose anything..." |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Corrected capitalization of 'goose' to 'Goose' for consistency with product branding.
| placeholder="Ask goose anything..." | |
| placeholder="Ask Goose anything..." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexhancock, should we consider this suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no - we want goose as a product name to always be lowercase
@alexhancock , Update the UI now it fills the whole margins :
|
* main: (60 commits) fix: add standard context menu items to prevent empty right-click menu (#5616) Bump openapi in prepare-release (#5611) docs: add access control section to Developer tutorial (#5615) Token state not showing on load, or after message is finished. (#5606) Change the other location too (#5608) feat(ui): bring back quick launcher (#5144) Support platform tools through CLI (#5570) Avoid web double write (#5601) fix: gemini flash -> pro for mcp smoke tests (#5574) Manual compaction test and fix (#5568) fix: tidy up claude cli handling (#5594) Remove jetbrains (#5602) feat(githubcopilot): add support for newer Copilot AI Models (#5603) fix: customised recipe to yaml string to avoid minininjia parsing error (#5494) Add pending extension indicator to extension panel (#5493) Add environment subsition for auth blocks (#5439) acp: ToolCallLocations and working cancellation (#5588) feat(providers): add Mistral AI provider (#5009) Listen for ctrl-c during provider request (#5585) Also accept null as description, not just missing (#5589) ...
* main: (31 commits) Standardize CLI argument flags and update documentation (#5516) Release 1.13.0 fix: move goosehints/AGENTS.md handling to goose, and out of developer extension (#5575) fix: add standard context menu items to prevent empty right-click menu (#5616) Bump openapi in prepare-release (#5611) docs: add access control section to Developer tutorial (#5615) Token state not showing on load, or after message is finished. (#5606) Change the other location too (#5608) feat(ui): bring back quick launcher (#5144) Support platform tools through CLI (#5570) Avoid web double write (#5601) fix: gemini flash -> pro for mcp smoke tests (#5574) Manual compaction test and fix (#5568) fix: tidy up claude cli handling (#5594) Remove jetbrains (#5602) feat(githubcopilot): add support for newer Copilot AI Models (#5603) fix: customised recipe to yaml string to avoid minininjia parsing error (#5494) Add pending extension indicator to extension panel (#5493) Add environment subsition for auth blocks (#5439) acp: ToolCallLocations and working cancellation (#5588) ...
* main: (21 commits) differentiate debug/release in cache key (#5613) Unify subrecipe and subagent execution through shared recipe pipeline (#5082) Standardize CLI argument flags and update documentation (#5516) Release 1.13.0 fix: move goosehints/AGENTS.md handling to goose, and out of developer extension (#5575) fix: add standard context menu items to prevent empty right-click menu (#5616) Bump openapi in prepare-release (#5611) docs: add access control section to Developer tutorial (#5615) Token state not showing on load, or after message is finished. (#5606) Change the other location too (#5608) feat(ui): bring back quick launcher (#5144) Support platform tools through CLI (#5570) Avoid web double write (#5601) fix: gemini flash -> pro for mcp smoke tests (#5574) Manual compaction test and fix (#5568) fix: tidy up claude cli handling (#5594) Remove jetbrains (#5602) feat(githubcopilot): add support for newer Copilot AI Models (#5603) fix: customised recipe to yaml string to avoid minininjia parsing error (#5494) Add pending extension indicator to extension panel (#5493) ...
Signed-off-by: Abhijay007 <[email protected]> Co-authored-by: Alex Hancock <[email protected]> Signed-off-by: fbalicchia <[email protected]>
* origin/main: (34 commits) Remove some logging (#5631) Use session IDs as task IDs for subagents instead of UUIDs (#5398) Fix the naming (#5628) fix: default tetrate model is broken, replace with haiku-4.5 (#5535) (#5587) Fetch less and use the right SHA (#5621) feat(ui): add custom macOS dock menu with New Window option (#5099) feat: remove hints from recipe prompts (#5622) docs: October 2025 Community All-Stars spotlight, Hacktoberfest edition (#5625) differentiate debug/release in cache key (#5613) Unify subrecipe and subagent execution through shared recipe pipeline (#5082) Standardize CLI argument flags and update documentation (#5516) Release 1.13.0 fix: move goosehints/AGENTS.md handling to goose, and out of developer extension (#5575) fix: add standard context menu items to prevent empty right-click menu (#5616) Bump openapi in prepare-release (#5611) docs: add access control section to Developer tutorial (#5615) Token state not showing on load, or after message is finished. (#5606) Change the other location too (#5608) feat(ui): bring back quick launcher (#5144) Support platform tools through CLI (#5570) ...
Signed-off-by: Abhijay007 <[email protected]> Co-authored-by: Alex Hancock <[email protected]>
Signed-off-by: Abhijay007 <[email protected]> Co-authored-by: Alex Hancock <[email protected]>
Signed-off-by: Abhijay007 <[email protected]> Co-authored-by: Alex Hancock <[email protected]> Signed-off-by: Blair Allan <[email protected]>

Closes: #4242
Pull Request Description
This PR aims to bring back the quick launcher and the fix launcher initial message handling so prompts from the universal shortcut open a chat window with the message pre-filled and auto-submitted.
Type of Change
Changes made:
Initial Message Flow: AddedpendingInitialMessagesmap to store initial messages until React signals ready, updated react-ready handler to send stored messages, and fixed routing to navigate to /pair when an initial message exists.Component Support: AddedinitialMessageprop toPair2andBaseChat2, enabled auto-submit for initial messages, and ensured the launcher creates chat windows with pre-filled and auto-submitted messages.Testing
Tested it in the Goose desktop by using the change
Screenshots/Demos (for UX changes)