From df7dd32929e03f3411ac2755ede18b2e12657c15 Mon Sep 17 00:00:00 2001 From: Lucas Giordano Date: Tue, 10 Feb 2026 17:47:06 +0100 Subject: [PATCH 1/3] feat: add pagination and filter flags to all list commands Expose --page, --page-size, and resource-specific filter flags (--only-active, --only-saved, --name) on all 7 paginated list commands so CLI users can paginate results and filter server-side instead of always fetching the first page with defaults. Co-Authored-By: Claude Opus 4.6 --- README.md | 23 +++++++++------- internal/cmd/agents.go | 17 +++++++++++- internal/cmd/flags_test.go | 27 +++++++++++++++++++ internal/cmd/functions.go | 24 +++++++++++++++-- internal/cmd/pagination.go | 24 +++++++++++++++++ internal/cmd/personas.go | 12 ++++++++- internal/cmd/profiles.go | 12 ++++++++- internal/cmd/sessions.go | 12 ++++++++- internal/cmd/vaults.go | 12 ++++++++- skills/notte-browser/SKILL.md | 24 ++++++++--------- .../references/account-management.md | 6 +++++ .../references/function-management.md | 7 +++++ .../references/session-management.md | 4 +++ 13 files changed, 175 insertions(+), 29 deletions(-) create mode 100644 internal/cmd/pagination.go diff --git a/README.md b/README.md index 0088239..b5fdfa2 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ notte auth status # Show authentication status ### Browser Sessions ```bash -notte sessions list # List all active sessions +notte sessions list [--page N] [--page-size N] [--only-active] # List sessions notte sessions start [flags] # Start a new session notte sessions status # Get current session status notte sessions stop # Stop current session @@ -140,7 +140,7 @@ notte page captcha-solve # Solve captcha ### AI Agents ```bash -notte agents list # List all AI agents +notte agents list [--page N] [--page-size N] [--only-active] [--only-saved] # List agents notte agents start --task "..." # Start a new AI agent (auto-uses current session) notte agents status # Get agent status (uses current agent) notte agents stop # Stop an agent (uses current agent) @@ -153,7 +153,7 @@ notte agents replay # Get agent execution replay ### Functions ```bash -notte functions list # List all functions +notte functions list [--page N] [--page-size N] [--only-active] # List functions notte functions create --file workflow.py # Create a new function notte functions show # View current function details notte functions show --function-id # View specific function details (different from current function) @@ -161,7 +161,7 @@ notte functions update --file workflow.py # Update current function code notte functions delete # Delete current function notte functions fork # Fork current function to new version notte functions run # Execute current function -notte functions runs # List runs for current function +notte functions runs [--page N] [--page-size N] [--only-active] # List runs for current function notte functions run-stop --run-id # Stop a running function execution notte functions run-metadata --run-id # Get run logs and results notte functions schedule --cron "0 9 * * *" # Schedule current function @@ -173,7 +173,7 @@ notte functions unschedule # Remove schedule from current function ### Vaults ```bash -notte vaults list # List all vaults +notte vaults list [--page N] [--page-size N] [--only-active] # List all vaults notte vaults create # Create a new vault notte vaults update --vault-id # Update vault metadata notte vaults delete --vault-id # Delete a vault @@ -186,7 +186,7 @@ notte vaults credentials delete --vault-id # Delete credentials ### Personas ```bash -notte personas list # List all personas +notte personas list [--page N] [--page-size N] [--only-active] # List all personas notte personas create # Create a new persona notte personas show --persona-id # View persona details notte personas delete --persona-id # Delete a persona @@ -197,7 +197,7 @@ notte personas sms --persona-id # List SMS messages ### Profiles ```bash -notte profiles list # List all profiles +notte profiles list [--page N] [--page-size N] [--name "..."] # List all profiles notte profiles create # Create a new profile notte profiles show --profile-id # View profile details notte profiles delete --profile-id # Delete a profile @@ -321,10 +321,13 @@ notte sessions stop ### JQ Filtering ```bash -# Get only active sessions -notte sessions list --output json | jq '.sessions[] | select(.status=="ACTIVE")' +# Get only active sessions (using built-in filter) +notte sessions list --only-active -# Extract session IDs +# Paginate through results +notte sessions list --page 2 --page-size 5 + +# Extract session IDs with jq notte sessions list --output json | jq -r '.sessions[].id' ``` diff --git a/internal/cmd/agents.go b/internal/cmd/agents.go index 8dfce9a..07a67c6 100644 --- a/internal/cmd/agents.go +++ b/internal/cmd/agents.go @@ -131,6 +131,10 @@ var agentsReplayCmd = &cobra.Command{ func init() { rootCmd.AddCommand(agentsCmd) agentsCmd.AddCommand(agentsListCmd) + registerPaginationFlags(agentsListCmd) + agentsListCmd.Flags().Bool("only-active", false, "Only return active agents") + agentsListCmd.Flags().Bool("only-saved", false, "Only return saved agents") + agentsCmd.AddCommand(agentsStartCmd) agentsCmd.AddCommand(agentsStatusCmd) agentsCmd.AddCommand(agentsStopCmd) @@ -163,7 +167,18 @@ func runAgentsList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() - params := &api.ListAgentsParams{} + params := &api.ListAgentsParams{ + Page: getPageFlag(cmd), + PageSize: getPageSizeFlag(cmd), + } + if cmd.Flags().Changed("only-active") { + v, _ := cmd.Flags().GetBool("only-active") + params.OnlyActive = &v + } + if cmd.Flags().Changed("only-saved") { + v, _ := cmd.Flags().GetBool("only-saved") + params.OnlySaved = &v + } resp, err := client.Client().ListAgentsWithResponse(ctx, params) if err != nil { return fmt.Errorf("API request failed: %w", err) diff --git a/internal/cmd/flags_test.go b/internal/cmd/flags_test.go index 63822ba..08bf0b5 100644 --- a/internal/cmd/flags_test.go +++ b/internal/cmd/flags_test.go @@ -3,6 +3,7 @@ package cmd import ( "testing" + "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -106,3 +107,29 @@ func TestNoGenericIDFlags(t *testing.T) { t.Error("All ID flags should be resource-specific (e.g., --session-id, --function-id, --vault-id)") } } + +// TestPaginatedListCommandsHaveFlags ensures all paginated list commands +// expose --page, --page-size, and their resource-specific filter flags. +func TestPaginatedListCommandsHaveFlags(t *testing.T) { + paginatedCommands := []struct { + cmd *cobra.Command + path string + requiredFlags []string + }{ + {sessionsListCmd, "sessions list", []string{"page", "page-size", "only-active"}}, + {agentsListCmd, "agents list", []string{"page", "page-size", "only-active", "only-saved"}}, + {functionsListCmd, "functions list", []string{"page", "page-size", "only-active"}}, + {functionsRunsCmd, "functions runs", []string{"page", "page-size", "only-active"}}, + {personasListCmd, "personas list", []string{"page", "page-size", "only-active"}}, + {profilesListCmd, "profiles list", []string{"page", "page-size", "name"}}, + {vaultsListCmd, "vaults list", []string{"page", "page-size", "only-active"}}, + } + + for _, tc := range paginatedCommands { + for _, flag := range tc.requiredFlags { + if tc.cmd.Flags().Lookup(flag) == nil { + t.Errorf("%s: missing required flag --%s", tc.path, flag) + } + } + } +} diff --git a/internal/cmd/functions.go b/internal/cmd/functions.go index 9dcb3ed..2975780 100644 --- a/internal/cmd/functions.go +++ b/internal/cmd/functions.go @@ -201,12 +201,18 @@ var functionsUnscheduleCmd = &cobra.Command{ func init() { rootCmd.AddCommand(functionsCmd) functionsCmd.AddCommand(functionsListCmd) + registerPaginationFlags(functionsListCmd) + functionsListCmd.Flags().Bool("only-active", false, "Only return active functions") + functionsCmd.AddCommand(functionsCreateCmd) functionsCmd.AddCommand(functionsShowCmd) functionsCmd.AddCommand(functionsUpdateCmd) functionsCmd.AddCommand(functionsDeleteCmd) functionsCmd.AddCommand(functionsRunCmd) functionsCmd.AddCommand(functionsRunsCmd) + registerPaginationFlags(functionsRunsCmd) + functionsRunsCmd.Flags().Bool("only-active", false, "Only return active runs") + functionsCmd.AddCommand(functionsForkCmd) functionsCmd.AddCommand(functionsRunStopCmd) functionsCmd.AddCommand(functionsRunMetadataCmd) @@ -277,7 +283,14 @@ func runFunctionsList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() - params := &api.ListFunctionsParams{} + params := &api.ListFunctionsParams{ + Page: getPageFlag(cmd), + PageSize: getPageSizeFlag(cmd), + } + if cmd.Flags().Changed("only-active") { + v, _ := cmd.Flags().GetBool("only-active") + params.OnlyActive = &v + } resp, err := client.Client().ListFunctionsWithResponse(ctx, params) if err != nil { return fmt.Errorf("API request failed: %w", err) @@ -596,7 +609,14 @@ func runFunctionRuns(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() - params := &api.ListFunctionRunsByFunctionIdParams{} + params := &api.ListFunctionRunsByFunctionIdParams{ + Page: getPageFlag(cmd), + PageSize: getPageSizeFlag(cmd), + } + if cmd.Flags().Changed("only-active") { + v, _ := cmd.Flags().GetBool("only-active") + params.OnlyActive = &v + } resp, err := client.Client().ListFunctionRunsByFunctionIdWithResponse(ctx, functionID, params) if err != nil { return fmt.Errorf("API request failed: %w", err) diff --git a/internal/cmd/pagination.go b/internal/cmd/pagination.go new file mode 100644 index 0000000..962cb6f --- /dev/null +++ b/internal/cmd/pagination.go @@ -0,0 +1,24 @@ +package cmd + +import "github.com/spf13/cobra" + +func registerPaginationFlags(cmd *cobra.Command) { + cmd.Flags().Int("page", 0, "Page number (1-indexed)") + cmd.Flags().Int("page-size", 0, "Number of items per page") +} + +func getPageFlag(cmd *cobra.Command) *int { + if cmd.Flags().Changed("page") { + v, _ := cmd.Flags().GetInt("page") + return &v + } + return nil +} + +func getPageSizeFlag(cmd *cobra.Command) *int { + if cmd.Flags().Changed("page-size") { + v, _ := cmd.Flags().GetInt("page-size") + return &v + } + return nil +} diff --git a/internal/cmd/personas.go b/internal/cmd/personas.go index 1dbb417..9f26033 100644 --- a/internal/cmd/personas.go +++ b/internal/cmd/personas.go @@ -59,6 +59,9 @@ var personasSmsCmd = &cobra.Command{ func init() { rootCmd.AddCommand(personasCmd) personasCmd.AddCommand(personasListCmd) + registerPaginationFlags(personasListCmd) + personasListCmd.Flags().Bool("only-active", false, "Only return active personas") + personasCmd.AddCommand(personasCreateCmd) personasCmd.AddCommand(personasShowCmd) personasCmd.AddCommand(personasDeleteCmd) @@ -94,7 +97,14 @@ func runPersonasList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() - params := &api.ListPersonasParams{} + params := &api.ListPersonasParams{ + Page: getPageFlag(cmd), + PageSize: getPageSizeFlag(cmd), + } + if cmd.Flags().Changed("only-active") { + v, _ := cmd.Flags().GetBool("only-active") + params.OnlyActive = &v + } resp, err := client.Client().ListPersonasWithResponse(ctx, params) if err != nil { return fmt.Errorf("API request failed: %w", err) diff --git a/internal/cmd/profiles.go b/internal/cmd/profiles.go index eabe9e0..d6149dd 100644 --- a/internal/cmd/profiles.go +++ b/internal/cmd/profiles.go @@ -45,6 +45,9 @@ var profilesDeleteCmd = &cobra.Command{ func init() { rootCmd.AddCommand(profilesCmd) profilesCmd.AddCommand(profilesListCmd) + registerPaginationFlags(profilesListCmd) + profilesListCmd.Flags().String("name", "", "Filter profiles by name") + profilesCmd.AddCommand(profilesCreateCmd) profilesCmd.AddCommand(profilesShowCmd) profilesCmd.AddCommand(profilesDeleteCmd) @@ -70,7 +73,14 @@ func runProfilesList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() - params := &api.ProfileListParams{} + params := &api.ProfileListParams{ + Page: getPageFlag(cmd), + PageSize: getPageSizeFlag(cmd), + } + if cmd.Flags().Changed("name") { + v, _ := cmd.Flags().GetString("name") + params.Name = &v + } resp, err := client.Client().ProfileListWithResponse(ctx, params) if err != nil { return fmt.Errorf("API request failed: %w", err) diff --git a/internal/cmd/sessions.go b/internal/cmd/sessions.go index a74c63a..f6761f2 100644 --- a/internal/cmd/sessions.go +++ b/internal/cmd/sessions.go @@ -262,6 +262,9 @@ var sessionsViewerCmd = &cobra.Command{ func init() { rootCmd.AddCommand(sessionsCmd) sessionsCmd.AddCommand(sessionsListCmd) + registerPaginationFlags(sessionsListCmd) + sessionsListCmd.Flags().Bool("only-active", false, "Only return active sessions") + sessionsCmd.AddCommand(sessionsStartCmd) sessionsCmd.AddCommand(sessionsStatusCmd) sessionsCmd.AddCommand(sessionsStopCmd) @@ -338,7 +341,14 @@ func runSessionsList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() - params := &api.ListSessionsParams{} + params := &api.ListSessionsParams{ + Page: getPageFlag(cmd), + PageSize: getPageSizeFlag(cmd), + } + if cmd.Flags().Changed("only-active") { + v, _ := cmd.Flags().GetBool("only-active") + params.OnlyActive = &v + } resp, err := client.Client().ListSessionsWithResponse(ctx, params) if err != nil { return fmt.Errorf("API request failed: %w", err) diff --git a/internal/cmd/vaults.go b/internal/cmd/vaults.go index 2457923..3472791 100644 --- a/internal/cmd/vaults.go +++ b/internal/cmd/vaults.go @@ -87,6 +87,9 @@ var vaultsCredentialsDeleteCmd = &cobra.Command{ func init() { rootCmd.AddCommand(vaultsCmd) vaultsCmd.AddCommand(vaultsListCmd) + registerPaginationFlags(vaultsListCmd) + vaultsListCmd.Flags().Bool("only-active", false, "Only return active vaults") + vaultsCmd.AddCommand(vaultsCreateCmd) vaultsCmd.AddCommand(vaultsUpdateCmd) vaultsCmd.AddCommand(vaultsDeleteCmd) @@ -137,7 +140,14 @@ func runVaultsList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() - params := &api.ListVaultsParams{} + params := &api.ListVaultsParams{ + Page: getPageFlag(cmd), + PageSize: getPageSizeFlag(cmd), + } + if cmd.Flags().Changed("only-active") { + v, _ := cmd.Flags().GetBool("only-active") + params.OnlyActive = &v + } resp, err := client.Client().ListVaultsWithResponse(ctx, params) if err != nil { return fmt.Errorf("API request failed: %w", err) diff --git a/skills/notte-browser/SKILL.md b/skills/notte-browser/SKILL.md index 0b08b19..a066359 100644 --- a/skills/notte-browser/SKILL.md +++ b/skills/notte-browser/SKILL.md @@ -63,8 +63,8 @@ notte sessions status # Stop current session notte sessions stop -# List active sessions -notte sessions list +# List sessions (with optional pagination and filters) +notte sessions list [--page N] [--page-size N] [--only-active] ``` **Note:** When you start a session, it automatically becomes the "current" session (i.e NOTTE_SESSION_ID environment variable is set). All subsequent commands use this session by default. Use `--session-id ` only when you need to manage multiple sessions simultaneously or reference a specific session. @@ -183,8 +183,8 @@ notte page form-fill --data '{"email": "test@example.com", "name": "John"}' Start and manage AI-powered browser agents: ```bash -# List all agents -notte agents list +# List all agents (with optional pagination and filters) +notte agents list [--page N] [--page-size N] [--only-active] [--only-saved] # Start a new agent (auto-uses current session if active) notte agents start --task "Navigate to example.com and extract the main heading" @@ -219,8 +219,8 @@ notte agents replay Create, manage, and schedule reusable workflows: ```bash -# List all functions -notte functions list +# List all functions (with optional pagination and filters) +notte functions list [--page N] [--page-size N] [--only-active] # Create a function from a workflow file notte functions create --file workflow.py [--name "My Function"] [--description "..."] [--shared] @@ -237,8 +237,8 @@ notte functions delete # Run current function notte functions run -# List runs for current function -notte functions runs +# List runs for current function (with optional pagination and filters) +notte functions runs [--page N] [--page-size N] [--only-active] # Stop a running function execution notte functions run-stop --run-id @@ -264,8 +264,8 @@ notte functions fork --function-id **Personas** - Auto-generated identities with email/phone: ```bash -# List personas -notte personas list +# List personas (with optional pagination and filters) +notte personas list [--page N] [--page-size N] [--only-active] # Create a persona notte personas create [--create-phone-number] [--create-vault] @@ -286,8 +286,8 @@ notte personas sms --persona-id **Vaults** - Store your own credentials: ```bash -# List vaults -notte vaults list +# List vaults (with optional pagination and filters) +notte vaults list [--page N] [--page-size N] [--only-active] # Create a vault notte vaults create [--name "My Vault"] diff --git a/skills/notte-browser/references/account-management.md b/skills/notte-browser/references/account-management.md index b453835..316adb9 100644 --- a/skills/notte-browser/references/account-management.md +++ b/skills/notte-browser/references/account-management.md @@ -43,6 +43,9 @@ notte personas create --create-vault # List all personas notte personas list +# With pagination and filters +notte personas list --page 1 --page-size 20 --only-active + # View persona details notte personas show --persona-id @@ -148,6 +151,9 @@ notte vaults create --name "Work Accounts" # List vaults notte vaults list +# With pagination and filters +notte vaults list --page 1 --page-size 20 --only-active + # Update vault name notte vaults update --vault-id --name "Personal Accounts" diff --git a/skills/notte-browser/references/function-management.md b/skills/notte-browser/references/function-management.md index 226284b..4c12215 100644 --- a/skills/notte-browser/references/function-management.md +++ b/skills/notte-browser/references/function-management.md @@ -255,7 +255,11 @@ notte functions run-metadata --run-id -o json | jq '.result' ### List Functions ```bash +# List all functions notte functions list + +# With pagination and filters +notte functions list --page 1 --page-size 20 --only-active ``` Output includes function ID, name, description, and creation date. @@ -299,6 +303,9 @@ Starts a new function run and returns the run ID. ```bash # List all runs for current function notte functions runs + +# With pagination and filters +notte functions runs --page 1 --page-size 10 --only-active ``` Output includes: diff --git a/skills/notte-browser/references/session-management.md b/skills/notte-browser/references/session-management.md index 0c545e7..5c9537b 100644 --- a/skills/notte-browser/references/session-management.md +++ b/skills/notte-browser/references/session-management.md @@ -291,7 +291,11 @@ notte sessions status ### List All Sessions ```bash +# List all sessions notte sessions list + +# With pagination and filters +notte sessions list --page 2 --page-size 10 --only-active ``` ## Stopping Sessions From 0d56125b7cea3866d95232b6e952c1369314c688 Mon Sep 17 00:00:00 2001 From: Lucas Giordano Date: Tue, 10 Feb 2026 17:53:34 +0100 Subject: [PATCH 2/3] chore: regenerate SDK from latest OpenAPI spec Co-Authored-By: Claude Opus 4.6 --- internal/api/client.gen.go | 351 +-------------------------- internal/cmd/agentstart_flags.gen.go | 2 +- 2 files changed, 14 insertions(+), 339 deletions(-) diff --git a/internal/api/client.gen.go b/internal/api/client.gen.go index a147e5c..3be4205 100644 --- a/internal/api/client.gen.go +++ b/internal/api/client.gen.go @@ -69,16 +69,10 @@ const ( DeletePersonaResponseStatusSuccess DeletePersonaResponseStatus = "success" ) -// Defines values for DeletePhoneNumberResponseStatus. -const ( - DeletePhoneNumberResponseStatusFailure DeletePhoneNumberResponseStatus = "failure" - DeletePhoneNumberResponseStatusSuccess DeletePhoneNumberResponseStatus = "success" -) - // Defines values for DeleteVaultResponseStatus. const ( - DeleteVaultResponseStatusFailure DeleteVaultResponseStatus = "failure" - DeleteVaultResponseStatusSuccess DeleteVaultResponseStatus = "success" + Failure DeleteVaultResponseStatus = "failure" + Success DeleteVaultResponseStatus = "success" ) // Defines values for FunctionRunUpdateRequestStatus. @@ -123,17 +117,17 @@ const ( // Defines values for LlmModel. const ( - AnthropicclaudeSonnet4520250929 LlmModel = "anthropic/claude-sonnet-4-5-20250929" - Cerebrasllama3370b LlmModel = "cerebras/llama-3.3-70b" - DeepseekdeepseekR1 LlmModel = "deepseek/deepseek-r1" - Geminigemini25Flash LlmModel = "gemini/gemini-2.5-flash" - Groqllama3370bVersatile LlmModel = "groq/llama-3.3-70b-versatile" - MoonshotkimiK25 LlmModel = "moonshot/kimi-k2.5" - Openaigpt4o LlmModel = "openai/gpt-4o" - Openroutergooglegemma327bIt LlmModel = "openrouter/google/gemma-3-27b-it" - PerplexitysonarPro LlmModel = "perplexity/sonar-pro" - TogetherAimetaLlamaLlama3370BInstructTurbo LlmModel = "together_ai/meta-llama/Llama-3.3-70B-Instruct-Turbo" - VertexAigemini25Flash LlmModel = "vertex_ai/gemini-2.5-flash" + AnthropicclaudeSonnet4520250929 LlmModel = "anthropic/claude-sonnet-4-5-20250929" + CerebrasgptOss120b LlmModel = "cerebras/gpt-oss-120b" + DeepseekdeepseekR1 LlmModel = "deepseek/deepseek-r1" + Geminigemini25Flash LlmModel = "gemini/gemini-2.5-flash" + GroqgptOss120b LlmModel = "groq/gpt-oss-120b" + MoonshotkimiK25 LlmModel = "moonshot/kimi-k2.5" + Openaigpt4o LlmModel = "openai/gpt-4o" + Openroutergooglegemma327bIt LlmModel = "openrouter/google/gemma-3-27b-it" + PerplexitysonarPro LlmModel = "perplexity/sonar-pro" + TogetherAimetaLlamallama3370bInstruct LlmModel = "together_ai/meta-llama/llama-3.3-70b-instruct" + VertexAigemini25Flash LlmModel = "vertex_ai/gemini-2.5-flash" ) // Defines values for NetworkLogFileType. @@ -841,15 +835,6 @@ type Cookie struct { Value string `json:"value"` } -// CreatePhoneNumberResponse defines model for CreatePhoneNumberResponse. -type CreatePhoneNumberResponse struct { - // PhoneNumber The phone number that was created - PhoneNumber string `json:"phone_number"` - - // Status Status of the created virtual number - Status string `json:"status"` -} - // Credential defines model for Credential. type Credential struct { Email *string `json:"email"` @@ -947,18 +932,6 @@ type DeletePersonaResponse struct { // DeletePersonaResponseStatus Status of the deletion type DeletePersonaResponseStatus string -// DeletePhoneNumberResponse defines model for DeletePhoneNumberResponse. -type DeletePhoneNumberResponse struct { - // Message Message of the deletion - Message *string `json:"message,omitempty"` - - // Status Status of the deletion - Status DeletePhoneNumberResponseStatus `json:"status"` -} - -// DeletePhoneNumberResponseStatus Status of the deletion -type DeletePhoneNumberResponseStatus string - // DeleteVaultResponse defines model for DeleteVaultResponse. type DeleteVaultResponse struct { // Message Message of the deletion @@ -2770,18 +2743,6 @@ type PersonaSmsListParams struct { XNotteSdkVersion *string `json:"x-notte-sdk-version,omitempty"` } -// PersonaDeleteNumberParams defines parameters for PersonaDeleteNumber. -type PersonaDeleteNumberParams struct { - XNotteRequestOrigin *string `json:"x-notte-request-origin,omitempty"` - XNotteSdkVersion *string `json:"x-notte-sdk-version,omitempty"` -} - -// PersonaCreateNumberParams defines parameters for PersonaCreateNumber. -type PersonaCreateNumberParams struct { - XNotteRequestOrigin *string `json:"x-notte-request-origin,omitempty"` - XNotteSdkVersion *string `json:"x-notte-sdk-version,omitempty"` -} - // ProfileListParams defines parameters for ProfileList. type ProfileListParams struct { // Page Page number @@ -8139,12 +8100,6 @@ type ClientInterface interface { // PersonaSmsList request PersonaSmsList(ctx context.Context, personaId string, params *PersonaSmsListParams, reqEditors ...RequestEditorFn) (*http.Response, error) - // PersonaDeleteNumber request - PersonaDeleteNumber(ctx context.Context, personaId string, params *PersonaDeleteNumberParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // PersonaCreateNumber request - PersonaCreateNumber(ctx context.Context, personaId string, params *PersonaCreateNumberParams, reqEditors ...RequestEditorFn) (*http.Response, error) - // ProfileList request ProfileList(ctx context.Context, params *ProfileListParams, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -8626,30 +8581,6 @@ func (c *Client) PersonaSmsList(ctx context.Context, personaId string, params *P return c.Client.Do(req) } -func (c *Client) PersonaDeleteNumber(ctx context.Context, personaId string, params *PersonaDeleteNumberParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewPersonaDeleteNumberRequest(c.Server, personaId, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) PersonaCreateNumber(ctx context.Context, personaId string, params *PersonaCreateNumberParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewPersonaCreateNumberRequest(c.Server, personaId, params) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - func (c *Client) ProfileList(ctx context.Context, params *ProfileListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewProfileListRequest(c.Server, params) if err != nil { @@ -11291,126 +11222,6 @@ func NewPersonaSmsListRequest(server string, personaId string, params *PersonaSm return req, nil } -// NewPersonaDeleteNumberRequest generates requests for PersonaDeleteNumber -func NewPersonaDeleteNumberRequest(server string, personaId string, params *PersonaDeleteNumberParams) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "persona_id", runtime.ParamLocationPath, personaId) - if err != nil { - return nil, err - } - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/personas/%s/sms/number", pathParam0) - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("DELETE", queryURL.String(), nil) - if err != nil { - return nil, err - } - - if params != nil { - - if params.XNotteRequestOrigin != nil { - var headerParam0 string - - headerParam0, err = runtime.StyleParamWithLocation("simple", false, "x-notte-request-origin", runtime.ParamLocationHeader, *params.XNotteRequestOrigin) - if err != nil { - return nil, err - } - - req.Header.Set("x-notte-request-origin", headerParam0) - } - - if params.XNotteSdkVersion != nil { - var headerParam1 string - - headerParam1, err = runtime.StyleParamWithLocation("simple", false, "x-notte-sdk-version", runtime.ParamLocationHeader, *params.XNotteSdkVersion) - if err != nil { - return nil, err - } - - req.Header.Set("x-notte-sdk-version", headerParam1) - } - - } - - return req, nil -} - -// NewPersonaCreateNumberRequest generates requests for PersonaCreateNumber -func NewPersonaCreateNumberRequest(server string, personaId string, params *PersonaCreateNumberParams) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "persona_id", runtime.ParamLocationPath, personaId) - if err != nil { - return nil, err - } - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/personas/%s/sms/number", pathParam0) - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), nil) - if err != nil { - return nil, err - } - - if params != nil { - - if params.XNotteRequestOrigin != nil { - var headerParam0 string - - headerParam0, err = runtime.StyleParamWithLocation("simple", false, "x-notte-request-origin", runtime.ParamLocationHeader, *params.XNotteRequestOrigin) - if err != nil { - return nil, err - } - - req.Header.Set("x-notte-request-origin", headerParam0) - } - - if params.XNotteSdkVersion != nil { - var headerParam1 string - - headerParam1, err = runtime.StyleParamWithLocation("simple", false, "x-notte-sdk-version", runtime.ParamLocationHeader, *params.XNotteSdkVersion) - if err != nil { - return nil, err - } - - req.Header.Set("x-notte-sdk-version", headerParam1) - } - - } - - return req, nil -} - // NewProfileListRequest generates requests for ProfileList func NewProfileListRequest(server string, params *ProfileListParams) (*http.Request, error) { var err error @@ -14062,12 +13873,6 @@ type ClientWithResponsesInterface interface { // PersonaSmsListWithResponse request PersonaSmsListWithResponse(ctx context.Context, personaId string, params *PersonaSmsListParams, reqEditors ...RequestEditorFn) (*PersonaSmsListResult, error) - // PersonaDeleteNumberWithResponse request - PersonaDeleteNumberWithResponse(ctx context.Context, personaId string, params *PersonaDeleteNumberParams, reqEditors ...RequestEditorFn) (*PersonaDeleteNumberResult, error) - - // PersonaCreateNumberWithResponse request - PersonaCreateNumberWithResponse(ctx context.Context, personaId string, params *PersonaCreateNumberParams, reqEditors ...RequestEditorFn) (*PersonaCreateNumberResult, error) - // ProfileListWithResponse request ProfileListWithResponse(ctx context.Context, params *ProfileListParams, reqEditors ...RequestEditorFn) (*ProfileListResult, error) @@ -14785,52 +14590,6 @@ func (r PersonaSmsListResult) StatusCode() int { return 0 } -type PersonaDeleteNumberResult struct { - Body []byte - HTTPResponse *http.Response - JSON200 *DeletePhoneNumberResponse - JSON422 *HTTPValidationError -} - -// Status returns HTTPResponse.Status -func (r PersonaDeleteNumberResult) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r PersonaDeleteNumberResult) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type PersonaCreateNumberResult struct { - Body []byte - HTTPResponse *http.Response - JSON200 *CreatePhoneNumberResponse - JSON422 *HTTPValidationError -} - -// Status returns HTTPResponse.Status -func (r PersonaCreateNumberResult) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r PersonaCreateNumberResult) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - type ProfileListResult struct { Body []byte HTTPResponse *http.Response @@ -15880,24 +15639,6 @@ func (c *ClientWithResponses) PersonaSmsListWithResponse(ctx context.Context, pe return ParsePersonaSmsListResult(rsp) } -// PersonaDeleteNumberWithResponse request returning *PersonaDeleteNumberResult -func (c *ClientWithResponses) PersonaDeleteNumberWithResponse(ctx context.Context, personaId string, params *PersonaDeleteNumberParams, reqEditors ...RequestEditorFn) (*PersonaDeleteNumberResult, error) { - rsp, err := c.PersonaDeleteNumber(ctx, personaId, params, reqEditors...) - if err != nil { - return nil, err - } - return ParsePersonaDeleteNumberResult(rsp) -} - -// PersonaCreateNumberWithResponse request returning *PersonaCreateNumberResult -func (c *ClientWithResponses) PersonaCreateNumberWithResponse(ctx context.Context, personaId string, params *PersonaCreateNumberParams, reqEditors ...RequestEditorFn) (*PersonaCreateNumberResult, error) { - rsp, err := c.PersonaCreateNumber(ctx, personaId, params, reqEditors...) - if err != nil { - return nil, err - } - return ParsePersonaCreateNumberResult(rsp) -} - // ProfileListWithResponse request returning *ProfileListResult func (c *ClientWithResponses) ProfileListWithResponse(ctx context.Context, params *ProfileListParams, reqEditors ...RequestEditorFn) (*ProfileListResult, error) { rsp, err := c.ProfileList(ctx, params, reqEditors...) @@ -17120,72 +16861,6 @@ func ParsePersonaSmsListResult(rsp *http.Response) (*PersonaSmsListResult, error return response, nil } -// ParsePersonaDeleteNumberResult parses an HTTP response from a PersonaDeleteNumberWithResponse call -func ParsePersonaDeleteNumberResult(rsp *http.Response) (*PersonaDeleteNumberResult, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &PersonaDeleteNumberResult{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest DeletePhoneNumberResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest HTTPValidationError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - } - - return response, nil -} - -// ParsePersonaCreateNumberResult parses an HTTP response from a PersonaCreateNumberWithResponse call -func ParsePersonaCreateNumberResult(rsp *http.Response) (*PersonaCreateNumberResult, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &PersonaCreateNumberResult{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest CreatePhoneNumberResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest HTTPValidationError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - } - - return response, nil -} - // ParseProfileListResult parses an HTTP response from a ProfileListWithResponse call func ParseProfileListResult(rsp *http.Response) (*ProfileListResult, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/internal/cmd/agentstart_flags.gen.go b/internal/cmd/agentstart_flags.gen.go index 0d15874..3f86f71 100644 --- a/internal/cmd/agentstart_flags.gen.go +++ b/internal/cmd/agentstart_flags.gen.go @@ -67,7 +67,7 @@ var ( func RegisterAgentStartFlags(cmd *cobra.Command) { cmd.Flags().IntVar(&AgentStartMaxSteps, "max-steps", 0, "The maximum number of steps the agent should take") cmd.Flags().StringVar(&AgentStartPersonaId, "persona-id", "", "The persona to use for the agent") - cmd.Flags().StringVar(&AgentStartReasoningModel, "reasoning-model", "", "The reasoning model to use (openai/gpt-4o, gemini/gemini-2.5-flash, vertex_ai/gemini-2.5-flash, openrouter/google/gemma-3-27b-it, cerebras/llama-3.3-70b, groq/llama-3.3-70b-versatile, perplexity/sonar-pro, deepseek/deepseek-r1, together_ai/meta-llama/Llama-3.3-70B-Instruct-Turbo, anthropic/claude-sonnet-4-5-20250929, moonshot/kimi-k2.5)") + cmd.Flags().StringVar(&AgentStartReasoningModel, "reasoning-model", "", "The reasoning model to use (openai/gpt-4o, gemini/gemini-2.5-flash, vertex_ai/gemini-2.5-flash, openrouter/google/gemma-3-27b-it, cerebras/gpt-oss-120b, groq/gpt-oss-120b, perplexity/sonar-pro, deepseek/deepseek-r1, together_ai/meta-llama/llama-3.3-70b-instruct, anthropic/claude-sonnet-4-5-20250929, moonshot/kimi-k2.5)") cmd.Flags().StringVar(&AgentStartResponseFormat, "response-format-json", "", "response-format configuration (JSON file path, e.g., @config.json)") cmd.Flags().StringVar(&AgentStartSessionId, "session-id", "", "The ID of the session to run the agent on") cmd.Flags().IntVar(&AgentStartSessionOffset, "session-offset", 0, "[Experimental] The step from which the agent should gather information from in the session. If none, fresh memory") From b434d0a77fc75a99f395696f6be3f0536c2110fe Mon Sep 17 00:00:00 2001 From: Lucas Giordano Date: Tue, 10 Feb 2026 18:24:34 +0100 Subject: [PATCH 3/3] fix: validate pagination flags reject values < 1 getPageFlag and getPageSizeFlag now return errors when the user explicitly passes a value less than 1, preventing invalid requests to the API since pages are 1-indexed. Co-Authored-By: Claude Opus 4.6 --- internal/cmd/agents.go | 12 ++++++++++-- internal/cmd/functions.go | 24 ++++++++++++++++++++---- internal/cmd/pagination.go | 24 +++++++++++++++++------- internal/cmd/personas.go | 12 ++++++++++-- internal/cmd/profiles.go | 12 ++++++++++-- internal/cmd/sessions.go | 12 ++++++++++-- internal/cmd/vaults.go | 12 ++++++++++-- 7 files changed, 87 insertions(+), 21 deletions(-) diff --git a/internal/cmd/agents.go b/internal/cmd/agents.go index 07a67c6..58fd457 100644 --- a/internal/cmd/agents.go +++ b/internal/cmd/agents.go @@ -167,9 +167,17 @@ func runAgentsList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() + page, err := getPageFlag(cmd) + if err != nil { + return err + } + pageSize, err := getPageSizeFlag(cmd) + if err != nil { + return err + } params := &api.ListAgentsParams{ - Page: getPageFlag(cmd), - PageSize: getPageSizeFlag(cmd), + Page: page, + PageSize: pageSize, } if cmd.Flags().Changed("only-active") { v, _ := cmd.Flags().GetBool("only-active") diff --git a/internal/cmd/functions.go b/internal/cmd/functions.go index 2975780..ca6ca58 100644 --- a/internal/cmd/functions.go +++ b/internal/cmd/functions.go @@ -283,9 +283,17 @@ func runFunctionsList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() + page, err := getPageFlag(cmd) + if err != nil { + return err + } + pageSize, err := getPageSizeFlag(cmd) + if err != nil { + return err + } params := &api.ListFunctionsParams{ - Page: getPageFlag(cmd), - PageSize: getPageSizeFlag(cmd), + Page: page, + PageSize: pageSize, } if cmd.Flags().Changed("only-active") { v, _ := cmd.Flags().GetBool("only-active") @@ -609,9 +617,17 @@ func runFunctionRuns(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() + page, err := getPageFlag(cmd) + if err != nil { + return err + } + pageSize, err := getPageSizeFlag(cmd) + if err != nil { + return err + } params := &api.ListFunctionRunsByFunctionIdParams{ - Page: getPageFlag(cmd), - PageSize: getPageSizeFlag(cmd), + Page: page, + PageSize: pageSize, } if cmd.Flags().Changed("only-active") { v, _ := cmd.Flags().GetBool("only-active") diff --git a/internal/cmd/pagination.go b/internal/cmd/pagination.go index 962cb6f..106d4ec 100644 --- a/internal/cmd/pagination.go +++ b/internal/cmd/pagination.go @@ -1,24 +1,34 @@ package cmd -import "github.com/spf13/cobra" +import ( + "fmt" + + "github.com/spf13/cobra" +) func registerPaginationFlags(cmd *cobra.Command) { cmd.Flags().Int("page", 0, "Page number (1-indexed)") cmd.Flags().Int("page-size", 0, "Number of items per page") } -func getPageFlag(cmd *cobra.Command) *int { +func getPageFlag(cmd *cobra.Command) (*int, error) { if cmd.Flags().Changed("page") { v, _ := cmd.Flags().GetInt("page") - return &v + if v < 1 { + return nil, fmt.Errorf("--page must be >= 1 (got %d)", v) + } + return &v, nil } - return nil + return nil, nil } -func getPageSizeFlag(cmd *cobra.Command) *int { +func getPageSizeFlag(cmd *cobra.Command) (*int, error) { if cmd.Flags().Changed("page-size") { v, _ := cmd.Flags().GetInt("page-size") - return &v + if v < 1 { + return nil, fmt.Errorf("--page-size must be >= 1 (got %d)", v) + } + return &v, nil } - return nil + return nil, nil } diff --git a/internal/cmd/personas.go b/internal/cmd/personas.go index 9f26033..478f983 100644 --- a/internal/cmd/personas.go +++ b/internal/cmd/personas.go @@ -97,9 +97,17 @@ func runPersonasList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() + page, err := getPageFlag(cmd) + if err != nil { + return err + } + pageSize, err := getPageSizeFlag(cmd) + if err != nil { + return err + } params := &api.ListPersonasParams{ - Page: getPageFlag(cmd), - PageSize: getPageSizeFlag(cmd), + Page: page, + PageSize: pageSize, } if cmd.Flags().Changed("only-active") { v, _ := cmd.Flags().GetBool("only-active") diff --git a/internal/cmd/profiles.go b/internal/cmd/profiles.go index d6149dd..d89beb7 100644 --- a/internal/cmd/profiles.go +++ b/internal/cmd/profiles.go @@ -73,9 +73,17 @@ func runProfilesList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() + page, err := getPageFlag(cmd) + if err != nil { + return err + } + pageSize, err := getPageSizeFlag(cmd) + if err != nil { + return err + } params := &api.ProfileListParams{ - Page: getPageFlag(cmd), - PageSize: getPageSizeFlag(cmd), + Page: page, + PageSize: pageSize, } if cmd.Flags().Changed("name") { v, _ := cmd.Flags().GetString("name") diff --git a/internal/cmd/sessions.go b/internal/cmd/sessions.go index f6761f2..092e727 100644 --- a/internal/cmd/sessions.go +++ b/internal/cmd/sessions.go @@ -341,9 +341,17 @@ func runSessionsList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() + page, err := getPageFlag(cmd) + if err != nil { + return err + } + pageSize, err := getPageSizeFlag(cmd) + if err != nil { + return err + } params := &api.ListSessionsParams{ - Page: getPageFlag(cmd), - PageSize: getPageSizeFlag(cmd), + Page: page, + PageSize: pageSize, } if cmd.Flags().Changed("only-active") { v, _ := cmd.Flags().GetBool("only-active") diff --git a/internal/cmd/vaults.go b/internal/cmd/vaults.go index 3472791..ba07928 100644 --- a/internal/cmd/vaults.go +++ b/internal/cmd/vaults.go @@ -140,9 +140,17 @@ func runVaultsList(cmd *cobra.Command, args []string) error { ctx, cancel := GetContextWithTimeout(cmd.Context()) defer cancel() + page, err := getPageFlag(cmd) + if err != nil { + return err + } + pageSize, err := getPageSizeFlag(cmd) + if err != nil { + return err + } params := &api.ListVaultsParams{ - Page: getPageFlag(cmd), - PageSize: getPageSizeFlag(cmd), + Page: page, + PageSize: pageSize, } if cmd.Flags().Changed("only-active") { v, _ := cmd.Flags().GetBool("only-active")