From 5b74b845bda7a77f639d64bdcac6323508eb943a Mon Sep 17 00:00:00 2001 From: Rafael Garcia Date: Sun, 18 Jan 2026 10:01:19 -0500 Subject: [PATCH] Remove -y flag from browsers delete, make non-interactive The -y/--yes confirmation flag on `kernel browsers delete` was overly cautious and not necessary. It also frequently trips up LLMs that attempt to use the CLI, as they either forget to pass the flag or get stuck waiting for interactive confirmation that never comes. Browser deletion is already an idempotent operation (deleting a non-existent browser succeeds), so requiring confirmation adds friction without meaningful protection. --- README.md | 3 +-- cmd/browsers.go | 42 +++--------------------------------------- cmd/browsers_test.go | 18 ++++-------------- 3 files changed, 8 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index c55d88b..af92648 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,6 @@ Commands with JSON output support: - `--output json`, `-o json` - Output raw JSON object - _Note: When a pool is specified, omit other session configuration flags—pool settings determine profile, proxy, viewport, etc._ - `kernel browsers delete ` - Delete a browser - - `-y, --yes` - Skip confirmation prompt - `kernel browsers view ` - Get live view URL for a browser - `--output json`, `-o json` - Output JSON with liveViewUrl - `kernel browsers get ` - Get detailed browser session info @@ -519,7 +518,7 @@ kernel browsers create --kiosk kernel browsers create --profile-name my-profile # Delete a browser -kernel browsers delete browser123 --yes +kernel browsers delete browser123 # Get live view URL kernel browsers view browser123 diff --git a/cmd/browsers.go b/cmd/browsers.go index dc661de..9297ef7 100644 --- a/cmd/browsers.go +++ b/cmd/browsers.go @@ -168,8 +168,7 @@ type BrowsersCreateInput struct { } type BrowsersDeleteInput struct { - Identifier string - SkipConfirm bool + Identifier string } type BrowsersViewInput struct { @@ -406,39 +405,7 @@ func buildBrowserTableData(sessionID, cdpURL, liveViewURL string, persistence ke } func (b BrowsersCmd) Delete(ctx context.Context, in BrowsersDeleteInput) error { - if !in.SkipConfirm { - found, err := b.browsers.Get(ctx, in.Identifier) - if err != nil { - return util.CleanedUpSdkError{Err: err} - } - - confirmMsg := fmt.Sprintf("Are you sure you want to delete browser \"%s\"?", in.Identifier) - pterm.DefaultInteractiveConfirm.DefaultText = confirmMsg - result, _ := pterm.DefaultInteractiveConfirm.Show() - if !result { - pterm.Info.Println("Deletion cancelled") - return nil - } - - if found.Persistence.ID == in.Identifier { - err = b.browsers.Delete(ctx, kernel.BrowserDeleteParams{PersistentID: in.Identifier}) - if err != nil && !util.IsNotFound(err) { - return util.CleanedUpSdkError{Err: err} - } - pterm.Success.Printf("Successfully deleted browser: %s\n", in.Identifier) - return nil - } - - pterm.Info.Printf("Deleting browser: %s\n", in.Identifier) - err = b.browsers.DeleteByID(ctx, in.Identifier) - if err != nil && !util.IsNotFound(err) { - return util.CleanedUpSdkError{Err: err} - } - pterm.Success.Printf("Successfully deleted browser: %s\n", in.Identifier) - return nil - } - - // Skip confirmation: try both deletion modes without listing first + // Try both deletion modes without confirmation // Treat not found as a success (idempotent delete) var nonNotFoundErrors []error @@ -2145,8 +2112,6 @@ func init() { browsersCreateCmd.Flags().String("pool-id", "", "Browser pool ID to acquire from (mutually exclusive with --pool-name)") browsersCreateCmd.Flags().String("pool-name", "", "Browser pool name to acquire from (mutually exclusive with --pool-id)") - // Add flags for delete command - browsersDeleteCmd.Flags().BoolP("yes", "y", false, "Skip confirmation prompt") // no flags for view; it takes a single positional argument } @@ -2305,13 +2270,12 @@ func runBrowsersCreate(cmd *cobra.Command, args []string) error { func runBrowsersDelete(cmd *cobra.Command, args []string) error { client := getKernelClient(cmd) - skipConfirm, _ := cmd.Flags().GetBool("yes") svc := client.Browsers b := BrowsersCmd{browsers: &svc} // Iterate all provided identifiers for _, identifier := range args { - if err := b.Delete(cmd.Context(), BrowsersDeleteInput{Identifier: identifier, SkipConfirm: skipConfirm}); err != nil { + if err := b.Delete(cmd.Context(), BrowsersDeleteInput{Identifier: identifier}); err != nil { return err } } diff --git a/cmd/browsers_test.go b/cmd/browsers_test.go index 7fcb120..2e9a6e8 100644 --- a/cmd/browsers_test.go +++ b/cmd/browsers_test.go @@ -243,7 +243,7 @@ func TestBrowsersCreate_PrintsErrorOnFailure(t *testing.T) { assert.Contains(t, err.Error(), "create failed") } -func TestBrowsersDelete_SkipConfirm_Success(t *testing.T) { +func TestBrowsersDelete_Success(t *testing.T) { setupStdoutCapture(t) fake := &FakeBrowsersService{ @@ -255,13 +255,13 @@ func TestBrowsersDelete_SkipConfirm_Success(t *testing.T) { }, } b := BrowsersCmd{browsers: fake} - _ = b.Delete(context.Background(), BrowsersDeleteInput{Identifier: "any", SkipConfirm: true}) + _ = b.Delete(context.Background(), BrowsersDeleteInput{Identifier: "any"}) out := outBuf.String() assert.Contains(t, out, "Successfully deleted (or already absent) browser: any") } -func TestBrowsersDelete_SkipConfirm_Failure(t *testing.T) { +func TestBrowsersDelete_Failure(t *testing.T) { setupStdoutCapture(t) fake := &FakeBrowsersService{ @@ -273,23 +273,13 @@ func TestBrowsersDelete_SkipConfirm_Failure(t *testing.T) { }, } b := BrowsersCmd{browsers: fake} - err := b.Delete(context.Background(), BrowsersDeleteInput{Identifier: "any", SkipConfirm: true}) + err := b.Delete(context.Background(), BrowsersDeleteInput{Identifier: "any"}) assert.Error(t, err) errMsg := err.Error() assert.True(t, strings.Contains(errMsg, "right failed") || strings.Contains(errMsg, "left failed"), "expected error message to contain either 'right failed' or 'left failed', got: %s", errMsg) } -func TestBrowsersDelete_WithConfirm_NotFound(t *testing.T) { - setupStdoutCapture(t) - - fake := &FakeBrowsersService{} - b := BrowsersCmd{browsers: fake} - err := b.Delete(context.Background(), BrowsersDeleteInput{Identifier: "missing", SkipConfirm: false}) - - assert.Error(t, err) - assert.Contains(t, err.Error(), "not found") -} func TestBrowsersView_ByID_PrintsURL(t *testing.T) { // Capture both pterm output and raw stdout