From dda69f07ea5d1209bf3c2ee02ea621eb00618bc6 Mon Sep 17 00:00:00 2001 From: Rob von Behren Date: Mon, 16 Mar 2026 23:22:38 -0700 Subject: [PATCH] fix: prevent double devbox creation when pressing Enter in interactive form The DevboxCreatePage had two overlapping Enter key handlers that both called handleCreate(): the FormTextInput's onSubmit prop and a global catch-all in the parent useInput handler. Since ink doesn't stop event propagation between useInput hooks, pressing Enter on any text field fired both handlers, creating two devboxes. Replaced the global catch-all with a specific handler for the create button field, and removed onSubmit from text inputs. Now only the create button and Ctrl+S trigger devbox creation, while each special field (metadata, gateways, etc.) retains its own Enter handler. Bonus: Fixed some unrelated build errors. --- src/components/DevboxCreatePage.tsx | 5 ++--- src/services/agentService.ts | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/components/DevboxCreatePage.tsx b/src/components/DevboxCreatePage.tsx index 6de5f97f..9fe8828c 100644 --- a/src/components/DevboxCreatePage.tsx +++ b/src/components/DevboxCreatePage.tsx @@ -459,8 +459,8 @@ export const DevboxCreatePage = ({ return; } - // Handle Enter on any field to submit - if (key.return) { + // Enter on the create button to submit + if (currentField === "create" && key.return) { handleCreate(); return; } @@ -1918,7 +1918,6 @@ export const DevboxCreatePage = ({ onChange={(value) => setFormData({ ...formData, [field.key]: value }) } - onSubmit={handleCreate} isActive={isActive} placeholder={field.placeholder} /> diff --git a/src/services/agentService.ts b/src/services/agentService.ts index 3f411770..70834659 100644 --- a/src/services/agentService.ts +++ b/src/services/agentService.ts @@ -11,6 +11,9 @@ export interface ListAgentsOptions { limit?: number; startingAfter?: string; publicOnly?: boolean; + privateOnly?: boolean; + name?: string; + search?: string; } export interface ListAgentsResult { @@ -32,6 +35,8 @@ export async function listAgents( limit?: number; starting_after?: string; is_public?: boolean; + name?: string; + search?: string; } = { limit: options.limit || 50, }; @@ -40,9 +45,18 @@ export async function listAgents( queryParams.starting_after = options.startingAfter; } - // Use API filter for public agents if (options.publicOnly) { queryParams.is_public = true; + } else if (options.privateOnly) { + queryParams.is_public = false; + } + + if (options.name) { + queryParams.name = options.name; + } + + if (options.search) { + queryParams.search = options.search; } const page = await client.agents.list(queryParams);