From 5eeac1cd0dd3390eec816490bee8c3864471a6de Mon Sep 17 00:00:00 2001 From: Alice Hau <110418948+ahau-square@users.noreply.github.com> Date: Wed, 2 Jul 2025 09:09:45 -0700 Subject: [PATCH] fix: fix desktop recipe url generation (#3209) Co-authored-by: Alice Hau --- ui/desktop/src/components/RecipeEditor.tsx | 3 ++- .../src/components/schedule/CreateScheduleModal.tsx | 2 +- ui/desktop/src/components/ui/DeepLinkModal.tsx | 3 ++- ui/desktop/src/main.ts | 8 ++++++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ui/desktop/src/components/RecipeEditor.tsx b/ui/desktop/src/components/RecipeEditor.tsx index 2dee8c6b..7e1323e0 100644 --- a/ui/desktop/src/components/RecipeEditor.tsx +++ b/ui/desktop/src/components/RecipeEditor.tsx @@ -21,7 +21,8 @@ interface RecipeEditorProps { // Function to generate a deep link from a recipe function generateDeepLink(recipe: Recipe): string { const configBase64 = Buffer.from(JSON.stringify(recipe)).toString('base64'); - return `goose://recipe?config=${configBase64}`; + const urlSafe = encodeURIComponent(configBase64); + return `goose://recipe?config=${urlSafe}`; } export default function RecipeEditor({ config }: RecipeEditorProps) { diff --git a/ui/desktop/src/components/schedule/CreateScheduleModal.tsx b/ui/desktop/src/components/schedule/CreateScheduleModal.tsx index 6b6b28c6..0d797e75 100644 --- a/ui/desktop/src/components/schedule/CreateScheduleModal.tsx +++ b/ui/desktop/src/components/schedule/CreateScheduleModal.tsx @@ -119,7 +119,7 @@ function parseDeepLink(deepLink: string): Recipe | null { return null; } - const configJson = Buffer.from(configParam, 'base64').toString('utf-8'); + const configJson = Buffer.from(decodeURIComponent(configParam), 'base64').toString('utf-8'); return JSON.parse(configJson) as Recipe; } catch (error) { console.error('Failed to parse deep link:', error); diff --git a/ui/desktop/src/components/ui/DeepLinkModal.tsx b/ui/desktop/src/components/ui/DeepLinkModal.tsx index 1c112feb..87e264a8 100644 --- a/ui/desktop/src/components/ui/DeepLinkModal.tsx +++ b/ui/desktop/src/components/ui/DeepLinkModal.tsx @@ -17,7 +17,8 @@ interface DeepLinkModalProps { // Function to generate a deep link from a bot config export function generateDeepLink(recipeConfig: RecipeConfig): string { const configBase64 = Buffer.from(JSON.stringify(recipeConfig)).toString('base64'); - return `goose://bot?config=${configBase64}`; + const urlSafe = encodeURIComponent(configBase64); + return `goose://bot?config=${urlSafe}`; } export function DeepLinkModal({ recipeConfig: initialRecipeConfig, onClose }: DeepLinkModalProps) { diff --git a/ui/desktop/src/main.ts b/ui/desktop/src/main.ts index f310eb16..b86e34d3 100644 --- a/ui/desktop/src/main.ts +++ b/ui/desktop/src/main.ts @@ -157,7 +157,9 @@ if (process.platform === 'win32') { const configParam = parsedUrl.searchParams.get('config'); if (configParam) { try { - recipeConfig = JSON.parse(Buffer.from(configParam, 'base64').toString('utf-8')); + recipeConfig = JSON.parse( + Buffer.from(decodeURIComponent(configParam), 'base64').toString('utf-8') + ); // Check if this is a scheduled job const scheduledJobId = parsedUrl.searchParams.get('scheduledJob'); @@ -260,7 +262,9 @@ function processProtocolUrl(parsedUrl: URL, window: BrowserWindow) { const configParam = parsedUrl.searchParams.get('config'); if (configParam) { try { - recipeConfig = JSON.parse(Buffer.from(configParam, 'base64').toString('utf-8')); + recipeConfig = JSON.parse( + Buffer.from(decodeURIComponent(configParam), 'base64').toString('utf-8') + ); // Check if this is a scheduled job const scheduledJobId = parsedUrl.searchParams.get('scheduledJob');