-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Enable recipe deeplink parameters for pre-population #5757
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
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 support for passing recipe parameters via URL query strings in deeplinks. Parameters can be specified using -p key=value flags in the CLI, which are then URL-encoded and appended to the deeplink URL. The frontend parses these parameters and uses them to pre-populate the Recipe Parameters dialog, with automatic submission when the recipe is accepted.
Key Changes
- CLI commands (
recipe deeplinkandrecipe open) now accept-p/--paramflags for specifying parameters - Deeplink URLs are generated with parameters as query string values (e.g.,
goose://recipe?config=<base64>&key1=value1&key2=value2) - Frontend parses parameters from deeplink URLs and stores them in chat context for pre-population and auto-submission
Reviewed Changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/desktop/src/main.ts | Modified parseRecipeDeeplink to extract query parameters and return RecipeDeeplinkData with config and parameters; updated createChat to accept recipeParameters |
| ui/desktop/src/hooks/useRecipeManager.ts | Added logic to read parameters from appConfig, initialize them in chat context, and auto-submit them when recipe is accepted |
| ui/desktop/src/components/ParameterInputModal.tsx | Added initialValues prop to pre-populate form fields with deeplink parameters |
| ui/desktop/src/components/BaseChat.tsx | Pass recipeParameterValues to ParameterInputModal as initialValues |
| crates/goose-cli/src/commands/recipe.rs | Added parameter parsing and URL construction logic; updated handle_deeplink and handle_open to accept params; added tests |
| crates/goose-cli/src/cli.rs | Added -p/--param flag to RecipeCommand::Deeplink and RecipeCommand::Open |
| crates/goose-cli/Cargo.toml | Added urlencoding dependency for encoding parameter values |
| Cargo.lock | Updated with urlencoding dependency |
384c0c2 to
3d64422
Compare
3d64422 to
3ef9437
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
Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.
3ef9437 to
7748ae7
Compare
7748ae7 to
d3f69a6
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
Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.
| recipeParameterValues: recipeParametersFromConfig.current, | ||
| }); | ||
| } | ||
| }, [chatContext, finalRecipe, chat.recipeParameterValues]); |
Copilot
AI
Nov 18, 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.
Missing chat in dependency array causes stale closure. The effect reads chat.recipeParameterValues but doesn't include chat in dependencies, which can lead to incorrect behavior when chat updates.
| }, [chatContext, finalRecipe, chat.recipeParameterValues]); | |
| }, [chatContext, finalRecipe, chat, chat.recipeParameterValues]); |
b560b4f to
0a33ab1
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
Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.
ui/desktop/src/main.ts
Outdated
| window.webContents.send('open-shared-session', pendingDeepLink); | ||
| } else if (parsedUrl.hostname === 'bot' || parsedUrl.hostname === 'recipe') { | ||
| const recipeDeeplink = parseRecipeDeeplink(parsedUrl.toString()); | ||
| const deeplinkData = parseRecipeDeeplink(pendingDeepLink || ''); |
Copilot
AI
Dec 1, 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.
Passing an empty string to parseRecipeDeeplink will throw (new URL('')) when pendingDeepLink is null; use pendingDeepLink ?? parsedUrl.toString() (or guard) so a valid URL string is always provided.
| const deeplinkData = parseRecipeDeeplink(pendingDeepLink || ''); | |
| const deeplinkData = parseRecipeDeeplink(pendingDeepLink ?? parsedUrl.toString()); |
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.
LGTM verified working locally with the trip planner recipe
goose://recipe?config=eyJ2ZXJzaW9uIjoiMS4wLjAiLCJ0aXRsZSI6IlRyaXAgcGxhbm5lciIsImRlc2NyaXB0aW9uIjoiUGxhbiB5b3VyIG5leHQgdmFjYXRpb24iLCJpbnN0cnVjdGlvbnMiOiJZb3UgYXJlIGEgdHJpcCBwbGFubmVyLiBSZXNlYXJjaCBkZXN0aW5hdGlvbnMgYW5kIGJlIHN1cmUgdG8gY2hlY2sgdGhlIHdlYXRoZXIuIiwicHJvbXB0IjoiSGVscCB0aGUgdXNlciBwbGFuIGEgdHJpcCB0byB7eyBkZXN0aW5hdGlvbiB9fSBmb3Ige3sgZHVyYXRpb24gfX0gZGF5cy4gQ3JlYXRlIGEgZGV0YWlsZWQgaXRpbmVyYXJ5IHRoYXQgaW5jbHVkZXM6XG4gLSBwbGFjZXMgdG8gdmlzaXRcbiAtIGFjdGl2aXRpZXMgdG8gZG9cbiAtIGxvY2FsIGN1aXNpbmUgdG8gdHJ5XG4gLSBhIHJvdWdoIGJ1ZGdldCBlc3RpbWF0ZVxuXG4gWW91IGNhbiB1c2UgdGhlIHt7IHJlY2lwZV9kaXIgfX0vdW5lc2NvLmNzdiBmaWxlIHRvIGNoZWNrIGluZm9ybWF0aW9uIG9uIFVORVNDTyB3b3JsZCBoZXJpdGFnZSBzaXRlc1xuIHRvIGluY2x1ZGUgaW4geW91ciB0cmF2ZWwgcGxhbi5cbiIsImV4dGVuc2lvbnMiOlt7InR5cGUiOiJzdGRpbyIsIm5hbWUiOiJ3ZWF0aGVyIiwiZGVzY3JpcHRpb24iOiJXZWF0aGVyIGRhdGEgZm9yIHRyaXAgcGxhbm5pbmciLCJjbWQiOiJ1dngiLCJhcmdzIjpbIm1jcF93ZWF0aGVyQGxhdGVzdCJdLCJlbnZzIjp7fSwiZW52X2tleXMiOltdLCJ0aW1lb3V0IjozMDAsImJ1bmRsZWQiOm51bGwsImF2YWlsYWJsZV90b29scyI6W119LHsidHlwZSI6ImJ1aWx0aW4iLCJuYW1lIjoiZGV2ZWxvcGVyIiwiZGVzY3JpcHRpb24iOiIiLCJkaXNwbGF5X25hbWUiOiJEZXZlbG9wZXIiLCJ0aW1lb3V0IjozMDAsImJ1bmRsZWQiOnRydWUsImF2YWlsYWJsZV90b29scyI6W119XSwic2V0dGluZ3MiOnsidGVtcGVyYXR1cmUiOjAuOH0sImFjdGl2aXRpZXMiOltdLCJhdXRob3IiOnsiY29udGFjdCI6ImRrYXR6In0sInBhcmFtZXRlcnMiOlt7ImtleSI6ImRlc3RpbmF0aW9uIiwiaW5wdXRfdHlwZSI6InN0cmluZyIsInJlcXVpcmVtZW50IjoicmVxdWlyZWQiLCJkZXNjcmlwdGlvbiI6IkRlc3RpbmF0aW9uIGZvciB0aGUgdHJpcC4gU2hvdWxkIGJlIGEgbGFyZ2UgcmVnaW9uIHdpdGggbXVsdGlwbGUgY2xpbWF0ZXMuIn0seyJrZXkiOiJkdXJhdGlvbiIsImlucHV0X3R5cGUiOiJudW1iZXIiLCJyZXF1aXJlbWVudCI6InJlcXVpcmVkIiwiZGVzY3JpcHRpb24iOiJOdW1iZXIgb2YgZGF5cyBmb3IgdGhlIHRyaXAuIn1dfQ&destination=africa&duration=10
Copilot says update all remaining generate_deeplink/handle_deeplink/handle_open call sites and tests to the new signatures (pass params or empty maps/arrays as appropriate) if you want to take a look?
|
|
||
| // Get recipe parameters from deeplink if available | ||
| const paramsFromConfig = | ||
| (window.appConfig.get('recipeParameters') as Record<string, string> | null | undefined) ?? null; |
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.
can you use optional chaining here like we do elsewhere in case its not available?
window.appConfig?.get
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.
Thanks. Looking!
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.
fixed
Of course! Looking |
@zanesq I just took a look. I believe all the call sites are updated. Let me know if I missed anything! |
0a33ab1 to
81c29b8
Compare
81c29b8 to
25fa308
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
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
| fn parse_params(params: &[String]) -> Result<HashMap<String, String>> { | ||
| let mut params_map = HashMap::new(); | ||
| for param in params { | ||
| let parts: Vec<&str> = param.splitn(2, '=').collect(); | ||
| if parts.len() != 2 { | ||
| return Err(anyhow::anyhow!( | ||
| "Invalid parameter format: '{}'. Expected format: key=value", | ||
| param | ||
| )); | ||
| } | ||
| params_map.insert(parts[0].to_string(), parts[1].to_string()); | ||
| } | ||
| Ok(params_map) | ||
| } |
Copilot
AI
Dec 3, 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 parse_params function lacks test coverage for edge cases such as:
- Parameters with
=in the value (e.g.,key=value=with=equals) - Empty parameter values (e.g.,
key=) - Parameters with special characters that need URL encoding
Consider adding dedicated unit tests for parse_params to ensure it handles these cases correctly.
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.
Cool, added some tests
| recipeParameterValues: recipeParametersFromConfig.current, | ||
| }); | ||
| } | ||
| }, [chatContext, finalRecipe, chat, chat.recipeParameterValues]); |
Copilot
AI
Dec 3, 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.
This useEffect has chat.recipeParameterValues in its dependency array, which will cause it to re-trigger when the effect itself updates recipeParameterValues (line 57), creating an unnecessary re-render cycle. Since the effect only runs when parameters haven't been set yet, remove chat.recipeParameterValues from the dependency array.
| }, [chatContext, finalRecipe, chat, chat.recipeParameterValues]); | |
| }, [chatContext, finalRecipe, chat]); |
Implements support for passing recipe parameters via deeplink URLs, allowing parameters to be pre-filled in the Recipe Parameters dialog when users open a recipe via deeplink. Changes: - CLI: Add -p/--param flag to deeplink and open commands for parameter specification - Rust: Parse URL query parameters and pass to frontend via appConfig - Frontend: Initialize recipe parameters from appConfig on load - UI: Pre-populate parameter modal with values from deeplink - Persist parameters in ref to handle React re-renders and state resets Usage: goose recipe deeplink <recipe> -p key1=value1 -p key2=value2 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
25fa308 to
75a829e
Compare
* origin/main: Update Anthropic and Google Gemini models to latest API versions (#5980) docs: chat recall tutorial (#5975) fix: `final assistant content cannot end with trailing whitespace` error from Anthropic (#5967) 5527 multiple file popups (#5905) Groq configure fix (#5833) added sidebar contextual information for firefox (#5433) docs: council of mine MCP (#5979) docs: nano banana extension (#5977) fix: remove prompt change, read model from config (#5976) Enable recipe deeplink parameters for pre-population (#5757) chore: upgrade npm packages (#5951) feat: ActionRequired (#5897) feat(acp): support loading sessions in acp (#5942) docs: add videos to multi-model page (#5938) docs: promote planning guide (#5934)
* main: fix params not being substituted in activities (#5992) blog: MCP Sampling (#5987) Update Anthropic and Google Gemini models to latest API versions (#5980) docs: chat recall tutorial (#5975) fix: `final assistant content cannot end with trailing whitespace` error from Anthropic (#5967) 5527 multiple file popups (#5905) Groq configure fix (#5833) added sidebar contextual information for firefox (#5433) docs: council of mine MCP (#5979) docs: nano banana extension (#5977) fix: remove prompt change, read model from config (#5976) Enable recipe deeplink parameters for pre-population (#5757)
…nses-streaming * 'main' of github.com:block/goose: blog: MCP Sampling (#5987) Update Anthropic and Google Gemini models to latest API versions (#5980) docs: chat recall tutorial (#5975) fix: `final assistant content cannot end with trailing whitespace` error from Anthropic (#5967) 5527 multiple file popups (#5905) Groq configure fix (#5833) added sidebar contextual information for firefox (#5433) docs: council of mine MCP (#5979) docs: nano banana extension (#5977) fix: remove prompt change, read model from config (#5976) Enable recipe deeplink parameters for pre-population (#5757) chore: upgrade npm packages (#5951) feat: ActionRequired (#5897) feat(acp): support loading sessions in acp (#5942) docs: add videos to multi-model page (#5938)
Summary
Add support for passing parameters via URL query strings in recipe deeplinks. Parameters are parsed from the URL, stored in chat context, and used to pre-populate the Recipe Parameters dialog.
Changes
-p/--paramflag torecipe deeplinkandrecipe opencommandsExample Usage
Generates:
Test Plan
Screen.Recording.2025-11-18.at.10.02.25.AM.mov
🤖 Generated with Claude Code