diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2daf110..08b4d2e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.7.12" + ".": "0.7.13" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index e3c221d..1c39cbf 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 94 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/agentmail/agentmail-ec4e26c46715d10a0de953666e890ab67f97e61f7355971ed728942f957100f8.yml -openapi_spec_hash: 74a582c32cd3a4f6e2afb1e84eccbb21 -config_hash: 8ab5eb1bfc282411f0283d386a319f23 +configured_endpoints: 91 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/agentmail/agentmail-82febf7e246170c880f45b5eece83e1c61a09db0ba33a727db9a1856b8e2e2e6.yml +openapi_spec_hash: 6c283e686c1bb42190fefbb0146af920 +config_hash: 79c13cf7727d64173933e0d367570632 diff --git a/CHANGELOG.md b/CHANGELOG.md index faa61ab..f8be50a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.7.13 (2026-07-10) + +Full Changelog: [v0.7.12...v0.7.13](https://github.com/agentmail-to/agentmail-cli/compare/v0.7.12...v0.7.13) + +### Features + +* **api:** api update ([4830642](https://github.com/agentmail-to/agentmail-cli/commit/4830642f1b660a451a354c8960bf5bde9ec312d8)) +* **api:** api update ([2dc9e62](https://github.com/agentmail-to/agentmail-cli/commit/2dc9e622b55e052aa44bcad4ccfe2489ed4aa908)) +* **api:** api update ([2508a62](https://github.com/agentmail-to/agentmail-cli/commit/2508a62a7abe87ea5044c75500ee931bf6742692)) +* **api:** api update ([f7e5d93](https://github.com/agentmail-to/agentmail-cli/commit/f7e5d93a4df98db8c2491a316717c0bd63ff9f08)) +* **api:** api update ([95de1df](https://github.com/agentmail-to/agentmail-cli/commit/95de1df13b2ff5a3146cd0ce528e5d305057ee08)) +* **api:** api update ([7f0959e](https://github.com/agentmail-to/agentmail-cli/commit/7f0959e4bbec8893c177ad4e155d7fc950d7c5e6)) +* **api:** api update ([5b5819c](https://github.com/agentmail-to/agentmail-cli/commit/5b5819c93bb814f0e13f4ce45d86212e32defe4f)) + ## 0.7.12 (2026-05-14) Full Changelog: [v0.7.11...v0.7.12](https://github.com/agentmail-to/agentmail-cli/compare/v0.7.11...v0.7.12) diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index d89cb34..5b65926 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -107,7 +107,6 @@ func init() { &inboxesList, &inboxesDelete, &inboxesGet, - &inboxesListMetrics, }, }, { @@ -251,14 +250,6 @@ func init() { &podsAPIKeysDelete, }, }, - { - Name: "pods:metrics", - Category: "API RESOURCE", - Suggest: true, - Commands: []*cli.Command{ - &podsMetricsQuery, - }, - }, { Name: "webhooks", Category: "API RESOURCE", @@ -316,14 +307,6 @@ func init() { &listsGet, }, }, - { - Name: "metrics", - Category: "API RESOURCE", - Suggest: true, - Commands: []*cli.Command{ - &metricsList, - }, - }, { Name: "organizations", Category: "API RESOURCE", diff --git a/pkg/cmd/domain.go b/pkg/cmd/domain.go index fe69bcd..816f1ce 100644 --- a/pkg/cmd/domain.go +++ b/pkg/cmd/domain.go @@ -25,12 +25,16 @@ var domainsCreate = cli.Command{ Required: true, BodyPath: "domain", }, - &requestflag.Flag[bool]{ + &requestflag.Flag[*bool]{ Name: "feedback-enabled", Usage: "Bounce and complaint notifications are sent to your inboxes.", - Required: true, BodyPath: "feedback_enabled", }, + &requestflag.Flag[*bool]{ + Name: "subdomains-enabled", + Usage: "Allow inboxes on any subdomain of this domain. Adds a required wildcard MX\nrecord (`*.`) to `records`.", + BodyPath: "subdomains_enabled", + }, }, Action: handleDomainsCreate, HideHelpCommand: true, @@ -52,6 +56,11 @@ var domainsUpdate = cli.Command{ Usage: "Bounce and complaint notifications are sent to your inboxes.", BodyPath: "feedback_enabled", }, + &requestflag.Flag[*bool]{ + Name: "subdomains-enabled", + Usage: "Allow inboxes on any subdomain of this domain. Adds a required wildcard MX\nrecord (`*.`) to `records`.", + BodyPath: "subdomains_enabled", + }, }, Action: handleDomainsUpdate, HideHelpCommand: true, diff --git a/pkg/cmd/domain_test.go b/pkg/cmd/domain_test.go index 0af23e7..c7d378f 100644 --- a/pkg/cmd/domain_test.go +++ b/pkg/cmd/domain_test.go @@ -17,6 +17,7 @@ func TestDomainsCreate(t *testing.T) { "domains", "create", "--domain", "domain", "--feedback-enabled=true", + "--subdomains-enabled=true", ) }) @@ -24,7 +25,8 @@ func TestDomainsCreate(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("" + "domain: domain\n" + - "feedback_enabled: true\n") + "feedback_enabled: true\n" + + "subdomains_enabled: true\n") mocktest.TestRunMockTestWithPipeAndFlags( t, pipeData, "--api-key", "string", @@ -42,12 +44,15 @@ func TestDomainsUpdate(t *testing.T) { "domains", "update", "--domain-id", "domain_id", "--feedback-enabled=true", + "--subdomains-enabled=true", ) }) t.Run("piping data", func(t *testing.T) { // Test piping YAML data over stdin - pipeData := []byte("feedback_enabled: true") + pipeData := []byte("" + + "feedback_enabled: true\n" + + "subdomains_enabled: true\n") mocktest.TestRunMockTestWithPipeAndFlags( t, pipeData, "--api-key", "string", diff --git a/pkg/cmd/inbox.go b/pkg/cmd/inbox.go index c6956ad..ae91601 100644 --- a/pkg/cmd/inbox.go +++ b/pkg/cmd/inbox.go @@ -31,9 +31,14 @@ var inboxesCreate = cli.Command{ }, &requestflag.Flag[*string]{ Name: "domain", - Usage: "Domain of address. Must be verified domain. Defaults to `agentmail.to`.", + Usage: "Domain of address. Must be a verified domain, or any subdomain of a\nverified domain that has subdomains enabled (e.g., `bot.example.com`).\nDefaults to `agentmail.to`.", BodyPath: "domain", }, + &requestflag.Flag[map[string]any]{ + Name: "metadata", + Usage: "Custom metadata to attach to the inbox.", + BodyPath: "metadata", + }, &requestflag.Flag[*string]{ Name: "username", Usage: "Username of address. Randomly generated if not specified.", @@ -55,12 +60,16 @@ var inboxesUpdate = cli.Command{ Required: true, PathParam: "inbox_id", }, - &requestflag.Flag[string]{ + &requestflag.Flag[*string]{ Name: "display-name", Usage: "Display name: `Display Name `.", - Required: true, BodyPath: "display_name", }, + &requestflag.Flag[map[string]any]{ + Name: "metadata", + Usage: "Metadata to merge into the inbox's existing metadata. Keys you include\nare added or overwritten; keys you omit are left unchanged. To remove a\nsingle key, send it with a null value. To clear all metadata, send\n`metadata` as null. Sending an empty object is rejected; use null to\nclear. Each update must include at least one of `display_name` or\n`metadata`.", + BodyPath: "metadata", + }, }, Action: handleInboxesUpdate, HideHelpCommand: true, @@ -123,52 +132,6 @@ var inboxesGet = cli.Command{ HideHelpCommand: true, } -var inboxesListMetrics = cli.Command{ - Name: "list-metrics", - Usage: "**CLI:**", - Suggest: true, - Flags: []cli.Flag{ - &requestflag.Flag[string]{ - Name: "inbox-id", - Usage: "The ID of the inbox.", - Required: true, - PathParam: "inbox_id", - }, - &requestflag.Flag[*bool]{ - Name: "descending", - Usage: "Sort in descending order.", - QueryPath: "descending", - }, - &requestflag.Flag[any]{ - Name: "end", - Usage: "End timestamp for the query.", - QueryPath: "end", - }, - &requestflag.Flag[any]{ - Name: "event-type", - Usage: "List of metric event types to query.", - QueryPath: "event_types", - }, - &requestflag.Flag[*int64]{ - Name: "limit", - Usage: "Limit on number of buckets to return.", - QueryPath: "limit", - }, - &requestflag.Flag[*string]{ - Name: "period", - Usage: "Period in number of seconds for the query.", - QueryPath: "period", - }, - &requestflag.Flag[any]{ - Name: "start", - Usage: "Start timestamp for the query.", - QueryPath: "start", - }, - }, - Action: handleInboxesListMetrics, - HideHelpCommand: true, -} - func handleInboxesCreate(ctx context.Context, cmd *cli.Command) error { client := agentmail.NewClient(getDefaultRequestOptions(cmd)...) unusedArgs := cmd.Args().Slice() @@ -366,52 +329,3 @@ func handleInboxesGet(ctx context.Context, cmd *cli.Command) error { Transform: transform, }) } - -func handleInboxesListMetrics(ctx context.Context, cmd *cli.Command) error { - client := agentmail.NewClient(getDefaultRequestOptions(cmd)...) - unusedArgs := cmd.Args().Slice() - if !cmd.IsSet("inbox-id") && len(unusedArgs) > 0 { - cmd.Set("inbox-id", unusedArgs[0]) - unusedArgs = unusedArgs[1:] - } - if len(unusedArgs) > 0 { - return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs) - } - - options, err := flagOptions( - cmd, - apiquery.NestedQueryFormatBrackets, - apiquery.ArrayQueryFormatComma, - EmptyBody, - false, - ) - if err != nil { - return err - } - - params := agentmail.InboxListMetricsParams{} - - var res []byte - options = append(options, option.WithResponseBodyInto(&res)) - _, err = client.Inboxes.ListMetrics( - ctx, - cmd.Value("inbox-id").(string), - params, - options..., - ) - if err != nil { - return err - } - - obj := gjson.ParseBytes(res) - format := cmd.Root().String("format") - explicitFormat := cmd.Root().IsSet("format") - transform := cmd.Root().String("transform") - return ShowJSON(obj, ShowJSONOpts{ - ExplicitFormat: explicitFormat, - Format: format, - RawOutput: cmd.Root().Bool("raw-output"), - Title: "inboxes list-metrics", - Transform: transform, - }) -} diff --git a/pkg/cmd/inbox_test.go b/pkg/cmd/inbox_test.go index b407dd8..212e650 100644 --- a/pkg/cmd/inbox_test.go +++ b/pkg/cmd/inbox_test.go @@ -18,6 +18,7 @@ func TestInboxesCreate(t *testing.T) { "--client-id", "client_id", "--display-name", "display_name", "--domain", "domain", + "--metadata", "{foo: string}", "--username", "username", ) }) @@ -28,6 +29,8 @@ func TestInboxesCreate(t *testing.T) { "client_id: client_id\n" + "display_name: display_name\n" + "domain: domain\n" + + "metadata:\n" + + " foo: string\n" + "username: username\n") mocktest.TestRunMockTestWithPipeAndFlags( t, pipeData, @@ -46,12 +49,16 @@ func TestInboxesUpdate(t *testing.T) { "inboxes", "update", "--inbox-id", "inbox_id", "--display-name", "display_name", + "--metadata", "{foo: string}", ) }) t.Run("piping data", func(t *testing.T) { // Test piping YAML data over stdin - pipeData := []byte("display_name: display_name") + pipeData := []byte("" + + "display_name: display_name\n" + + "metadata:\n" + + " foo: string\n") mocktest.TestRunMockTestWithPipeAndFlags( t, pipeData, "--api-key", "string", @@ -98,21 +105,3 @@ func TestInboxesGet(t *testing.T) { ) }) } - -func TestInboxesListMetrics(t *testing.T) { - t.Skip("Mock server tests are disabled") - t.Run("regular flags", func(t *testing.T) { - mocktest.TestRunMockTestWithFlags( - t, - "--api-key", "string", - "inboxes", "list-metrics", - "--inbox-id", "inbox_id", - "--descending=true", - "--end", "'2019-12-27T18:11:19.117Z'", - "--event-type", "[message.sent]", - "--limit", "0", - "--period", "period", - "--start", "'2019-12-27T18:11:19.117Z'", - ) - }) -} diff --git a/pkg/cmd/inboxmessage.go b/pkg/cmd/inboxmessage.go index 16e482d..eb4c4b8 100644 --- a/pkg/cmd/inboxmessage.go +++ b/pkg/cmd/inboxmessage.go @@ -48,7 +48,7 @@ var inboxesMessagesUpdate = cli.Command{ var inboxesMessagesList = cli.Command{ Name: "list", - Usage: "**CLI:**", + Usage: "Lists messages in the inbox, most recent first. Pass `from`, `to`, or `subject`\nto filter by substring. Filtered requests are served by search, which caps\n`limit` at 100. For relevance-ranked full-text search across sender, recipients,\nsubject, and message body, use `Search Messages`.", Suggest: true, Flags: []cli.Flag{ &requestflag.Flag[string]{ @@ -72,6 +72,11 @@ var inboxesMessagesList = cli.Command{ Usage: "Timestamp before which to filter by.", QueryPath: "before", }, + &requestflag.Flag[any]{ + Name: "from", + Usage: "Filter to messages whose sender contains this value (substring match). Repeatable; all values must match.", + QueryPath: "from", + }, &requestflag.Flag[*bool]{ Name: "include-blocked", Usage: "Include blocked in results.", @@ -107,6 +112,16 @@ var inboxesMessagesList = cli.Command{ Usage: "Page token for pagination.", QueryPath: "page_token", }, + &requestflag.Flag[any]{ + Name: "subject", + Usage: "Filter to messages whose subject contains this value (substring match). Repeatable; all values must match.", + QueryPath: "subject", + }, + &requestflag.Flag[any]{ + Name: "to", + Usage: "Filter to messages whose recipients (to, cc, or bcc) contain this value (substring match). Repeatable; all values must match.", + QueryPath: "to", + }, }, Action: handleInboxesMessagesList, HideHelpCommand: true, diff --git a/pkg/cmd/inboxmessage_test.go b/pkg/cmd/inboxmessage_test.go index d21c0e9..75c86bd 100644 --- a/pkg/cmd/inboxmessage_test.go +++ b/pkg/cmd/inboxmessage_test.go @@ -49,6 +49,7 @@ func TestInboxesMessagesList(t *testing.T) { "--after", "'2019-12-27T18:11:19.117Z'", "--ascending=true", "--before", "'2019-12-27T18:11:19.117Z'", + "--from", "[string]", "--include-blocked=true", "--include-spam=true", "--include-trash=true", @@ -56,6 +57,8 @@ func TestInboxesMessagesList(t *testing.T) { "--label", "[string]", "--limit", "0", "--page-token", "page_token", + "--subject", "[string]", + "--to", "[string]", ) }) } diff --git a/pkg/cmd/inboxthread.go b/pkg/cmd/inboxthread.go index 201208b..4b0b141 100644 --- a/pkg/cmd/inboxthread.go +++ b/pkg/cmd/inboxthread.go @@ -16,7 +16,7 @@ import ( var inboxesThreadsList = cli.Command{ Name: "list", - Usage: "**CLI:**", + Usage: "Lists threads in the inbox, most recent first. Pass `senders`, `recipients`, or\n`subject` to filter by substring. Filtered requests are served by search, which\ncaps `limit` at 100. For relevance-ranked full-text search, use\n`Search Threads`.", Suggest: true, Flags: []cli.Flag{ &requestflag.Flag[string]{ @@ -75,6 +75,21 @@ var inboxesThreadsList = cli.Command{ Usage: "Page token for pagination.", QueryPath: "page_token", }, + &requestflag.Flag[any]{ + Name: "recipient", + Usage: "Filter to threads whose recipients contain this value (substring match). Repeatable; all values must match.", + QueryPath: "recipients", + }, + &requestflag.Flag[any]{ + Name: "sender", + Usage: "Filter to threads whose senders contain this value (substring match). Repeatable; all values must match.", + QueryPath: "senders", + }, + &requestflag.Flag[any]{ + Name: "subject", + Usage: "Filter to threads whose subject contains this value (substring match). Repeatable; all values must match.", + QueryPath: "subject", + }, }, Action: handleInboxesThreadsList, HideHelpCommand: true, diff --git a/pkg/cmd/inboxthread_test.go b/pkg/cmd/inboxthread_test.go index 71c86ab..fd3e7f2 100644 --- a/pkg/cmd/inboxthread_test.go +++ b/pkg/cmd/inboxthread_test.go @@ -26,6 +26,9 @@ func TestInboxesThreadsList(t *testing.T) { "--label", "[string]", "--limit", "0", "--page-token", "page_token", + "--recipient", "[string]", + "--sender", "[string]", + "--subject", "[string]", ) }) } diff --git a/pkg/cmd/metric.go b/pkg/cmd/metric.go deleted file mode 100644 index 267ee13..0000000 --- a/pkg/cmd/metric.go +++ /dev/null @@ -1,96 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -package cmd - -import ( - "context" - "fmt" - - "github.com/agentmail-to/agentmail-cli/internal/apiquery" - "github.com/agentmail-to/agentmail-cli/internal/requestflag" - "github.com/agentmail-to/agentmail-go" - "github.com/agentmail-to/agentmail-go/option" - "github.com/tidwall/gjson" - "github.com/urfave/cli/v3" -) - -var metricsList = cli.Command{ - Name: "list", - Usage: "**CLI:**", - Suggest: true, - Flags: []cli.Flag{ - &requestflag.Flag[*bool]{ - Name: "descending", - Usage: "Sort in descending order.", - QueryPath: "descending", - }, - &requestflag.Flag[any]{ - Name: "end", - Usage: "End timestamp for the query.", - QueryPath: "end", - }, - &requestflag.Flag[any]{ - Name: "event-type", - Usage: "List of metric event types to query.", - QueryPath: "event_types", - }, - &requestflag.Flag[*int64]{ - Name: "limit", - Usage: "Limit on number of buckets to return.", - QueryPath: "limit", - }, - &requestflag.Flag[*string]{ - Name: "period", - Usage: "Period in number of seconds for the query.", - QueryPath: "period", - }, - &requestflag.Flag[any]{ - Name: "start", - Usage: "Start timestamp for the query.", - QueryPath: "start", - }, - }, - Action: handleMetricsList, - HideHelpCommand: true, -} - -func handleMetricsList(ctx context.Context, cmd *cli.Command) error { - client := agentmail.NewClient(getDefaultRequestOptions(cmd)...) - unusedArgs := cmd.Args().Slice() - - if len(unusedArgs) > 0 { - return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs) - } - - options, err := flagOptions( - cmd, - apiquery.NestedQueryFormatBrackets, - apiquery.ArrayQueryFormatComma, - EmptyBody, - false, - ) - if err != nil { - return err - } - - params := agentmail.MetricListParams{} - - var res []byte - options = append(options, option.WithResponseBodyInto(&res)) - _, err = client.Metrics.List(ctx, params, options...) - if err != nil { - return err - } - - obj := gjson.ParseBytes(res) - format := cmd.Root().String("format") - explicitFormat := cmd.Root().IsSet("format") - transform := cmd.Root().String("transform") - return ShowJSON(obj, ShowJSONOpts{ - ExplicitFormat: explicitFormat, - Format: format, - RawOutput: cmd.Root().Bool("raw-output"), - Title: "metrics list", - Transform: transform, - }) -} diff --git a/pkg/cmd/metric_test.go b/pkg/cmd/metric_test.go deleted file mode 100644 index 6b2757a..0000000 --- a/pkg/cmd/metric_test.go +++ /dev/null @@ -1,26 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -package cmd - -import ( - "testing" - - "github.com/agentmail-to/agentmail-cli/internal/mocktest" -) - -func TestMetricsList(t *testing.T) { - t.Skip("Mock server tests are disabled") - t.Run("regular flags", func(t *testing.T) { - mocktest.TestRunMockTestWithFlags( - t, - "--api-key", "string", - "metrics", "list", - "--descending=true", - "--end", "'2019-12-27T18:11:19.117Z'", - "--event-type", "[message.sent]", - "--limit", "0", - "--period", "period", - "--start", "'2019-12-27T18:11:19.117Z'", - ) - }) -} diff --git a/pkg/cmd/poddomain.go b/pkg/cmd/poddomain.go index 61083cd..9eda6e9 100644 --- a/pkg/cmd/poddomain.go +++ b/pkg/cmd/poddomain.go @@ -31,12 +31,16 @@ var podsDomainsCreate = cli.Command{ Required: true, BodyPath: "domain", }, - &requestflag.Flag[bool]{ + &requestflag.Flag[*bool]{ Name: "feedback-enabled", Usage: "Bounce and complaint notifications are sent to your inboxes.", - Required: true, BodyPath: "feedback_enabled", }, + &requestflag.Flag[*bool]{ + Name: "subdomains-enabled", + Usage: "Allow inboxes on any subdomain of this domain. Adds a required wildcard MX\nrecord (`*.`) to `records`.", + BodyPath: "subdomains_enabled", + }, }, Action: handlePodsDomainsCreate, HideHelpCommand: true, @@ -64,6 +68,11 @@ var podsDomainsUpdate = cli.Command{ Usage: "Bounce and complaint notifications are sent to your inboxes.", BodyPath: "feedback_enabled", }, + &requestflag.Flag[*bool]{ + Name: "subdomains-enabled", + Usage: "Allow inboxes on any subdomain of this domain. Adds a required wildcard MX\nrecord (`*.`) to `records`.", + BodyPath: "subdomains_enabled", + }, }, Action: handlePodsDomainsUpdate, HideHelpCommand: true, diff --git a/pkg/cmd/poddomain_test.go b/pkg/cmd/poddomain_test.go index 20c20be..fb8caeb 100644 --- a/pkg/cmd/poddomain_test.go +++ b/pkg/cmd/poddomain_test.go @@ -18,6 +18,7 @@ func TestPodsDomainsCreate(t *testing.T) { "--pod-id", "pod_id", "--domain", "domain", "--feedback-enabled=true", + "--subdomains-enabled=true", ) }) @@ -25,7 +26,8 @@ func TestPodsDomainsCreate(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("" + "domain: domain\n" + - "feedback_enabled: true\n") + "feedback_enabled: true\n" + + "subdomains_enabled: true\n") mocktest.TestRunMockTestWithPipeAndFlags( t, pipeData, "--api-key", "string", @@ -45,12 +47,15 @@ func TestPodsDomainsUpdate(t *testing.T) { "--pod-id", "pod_id", "--domain-id", "domain_id", "--feedback-enabled=true", + "--subdomains-enabled=true", ) }) t.Run("piping data", func(t *testing.T) { // Test piping YAML data over stdin - pipeData := []byte("feedback_enabled: true") + pipeData := []byte("" + + "feedback_enabled: true\n" + + "subdomains_enabled: true\n") mocktest.TestRunMockTestWithPipeAndFlags( t, pipeData, "--api-key", "string", diff --git a/pkg/cmd/podinbox.go b/pkg/cmd/podinbox.go index e7c797d..a25d841 100644 --- a/pkg/cmd/podinbox.go +++ b/pkg/cmd/podinbox.go @@ -37,9 +37,14 @@ var podsInboxesCreate = cli.Command{ }, &requestflag.Flag[*string]{ Name: "domain", - Usage: "Domain of address. Must be verified domain. Defaults to `agentmail.to`.", + Usage: "Domain of address. Must be a verified domain, or any subdomain of a\nverified domain that has subdomains enabled (e.g., `bot.example.com`).\nDefaults to `agentmail.to`.", BodyPath: "domain", }, + &requestflag.Flag[map[string]any]{ + Name: "metadata", + Usage: "Custom metadata to attach to the inbox.", + BodyPath: "metadata", + }, &requestflag.Flag[*string]{ Name: "username", Usage: "Username of address. Randomly generated if not specified.", @@ -67,12 +72,16 @@ var podsInboxesUpdate = cli.Command{ Required: true, PathParam: "inbox_id", }, - &requestflag.Flag[string]{ + &requestflag.Flag[*string]{ Name: "display-name", Usage: "Display name: `Display Name `.", - Required: true, BodyPath: "display_name", }, + &requestflag.Flag[map[string]any]{ + Name: "metadata", + Usage: "Metadata to merge into the inbox's existing metadata. Keys you include\nare added or overwritten; keys you omit are left unchanged. To remove a\nsingle key, send it with a null value. To clear all metadata, send\n`metadata` as null. Sending an empty object is rejected; use null to\nclear. Each update must include at least one of `display_name` or\n`metadata`.", + BodyPath: "metadata", + }, }, Action: handlePodsInboxesUpdate, HideHelpCommand: true, diff --git a/pkg/cmd/podinbox_test.go b/pkg/cmd/podinbox_test.go index 21fa725..d7de7fb 100644 --- a/pkg/cmd/podinbox_test.go +++ b/pkg/cmd/podinbox_test.go @@ -19,6 +19,7 @@ func TestPodsInboxesCreate(t *testing.T) { "--client-id", "client_id", "--display-name", "display_name", "--domain", "domain", + "--metadata", "{foo: string}", "--username", "username", ) }) @@ -29,6 +30,8 @@ func TestPodsInboxesCreate(t *testing.T) { "client_id: client_id\n" + "display_name: display_name\n" + "domain: domain\n" + + "metadata:\n" + + " foo: string\n" + "username: username\n") mocktest.TestRunMockTestWithPipeAndFlags( t, pipeData, @@ -49,12 +52,16 @@ func TestPodsInboxesUpdate(t *testing.T) { "--pod-id", "pod_id", "--inbox-id", "inbox_id", "--display-name", "display_name", + "--metadata", "{foo: string}", ) }) t.Run("piping data", func(t *testing.T) { // Test piping YAML data over stdin - pipeData := []byte("display_name: display_name") + pipeData := []byte("" + + "display_name: display_name\n" + + "metadata:\n" + + " foo: string\n") mocktest.TestRunMockTestWithPipeAndFlags( t, pipeData, "--api-key", "string", diff --git a/pkg/cmd/podmetric.go b/pkg/cmd/podmetric.go deleted file mode 100644 index 99c857d..0000000 --- a/pkg/cmd/podmetric.go +++ /dev/null @@ -1,110 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -package cmd - -import ( - "context" - "fmt" - - "github.com/agentmail-to/agentmail-cli/internal/apiquery" - "github.com/agentmail-to/agentmail-cli/internal/requestflag" - "github.com/agentmail-to/agentmail-go" - "github.com/agentmail-to/agentmail-go/option" - "github.com/tidwall/gjson" - "github.com/urfave/cli/v3" -) - -var podsMetricsQuery = cli.Command{ - Name: "query", - Usage: "**CLI:**", - Suggest: true, - Flags: []cli.Flag{ - &requestflag.Flag[string]{ - Name: "pod-id", - Usage: "ID of pod.", - Required: true, - PathParam: "pod_id", - }, - &requestflag.Flag[*bool]{ - Name: "descending", - Usage: "Sort in descending order.", - QueryPath: "descending", - }, - &requestflag.Flag[any]{ - Name: "end", - Usage: "End timestamp for the query.", - QueryPath: "end", - }, - &requestflag.Flag[any]{ - Name: "event-type", - Usage: "List of metric event types to query.", - QueryPath: "event_types", - }, - &requestflag.Flag[*int64]{ - Name: "limit", - Usage: "Limit on number of buckets to return.", - QueryPath: "limit", - }, - &requestflag.Flag[*string]{ - Name: "period", - Usage: "Period in number of seconds for the query.", - QueryPath: "period", - }, - &requestflag.Flag[any]{ - Name: "start", - Usage: "Start timestamp for the query.", - QueryPath: "start", - }, - }, - Action: handlePodsMetricsQuery, - HideHelpCommand: true, -} - -func handlePodsMetricsQuery(ctx context.Context, cmd *cli.Command) error { - client := agentmail.NewClient(getDefaultRequestOptions(cmd)...) - unusedArgs := cmd.Args().Slice() - if !cmd.IsSet("pod-id") && len(unusedArgs) > 0 { - cmd.Set("pod-id", unusedArgs[0]) - unusedArgs = unusedArgs[1:] - } - if len(unusedArgs) > 0 { - return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs) - } - - options, err := flagOptions( - cmd, - apiquery.NestedQueryFormatBrackets, - apiquery.ArrayQueryFormatComma, - EmptyBody, - false, - ) - if err != nil { - return err - } - - params := agentmail.PodMetricQueryParams{} - - var res []byte - options = append(options, option.WithResponseBodyInto(&res)) - _, err = client.Pods.Metrics.Query( - ctx, - cmd.Value("pod-id").(string), - params, - options..., - ) - if err != nil { - return err - } - - obj := gjson.ParseBytes(res) - format := cmd.Root().String("format") - explicitFormat := cmd.Root().IsSet("format") - transform := cmd.Root().String("transform") - return ShowJSON(obj, ShowJSONOpts{ - ExplicitFormat: explicitFormat, - Format: format, - RawOutput: cmd.Root().Bool("raw-output"), - Title: "pods:metrics query", - Transform: transform, - }) -} diff --git a/pkg/cmd/podmetric_test.go b/pkg/cmd/podmetric_test.go deleted file mode 100644 index 408bccc..0000000 --- a/pkg/cmd/podmetric_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -package cmd - -import ( - "testing" - - "github.com/agentmail-to/agentmail-cli/internal/mocktest" -) - -func TestPodsMetricsQuery(t *testing.T) { - t.Skip("Mock server tests are disabled") - t.Run("regular flags", func(t *testing.T) { - mocktest.TestRunMockTestWithFlags( - t, - "--api-key", "string", - "pods:metrics", "query", - "--pod-id", "pod_id", - "--descending=true", - "--end", "'2019-12-27T18:11:19.117Z'", - "--event-type", "[message.sent]", - "--limit", "0", - "--period", "period", - "--start", "'2019-12-27T18:11:19.117Z'", - ) - }) -} diff --git a/pkg/cmd/podthread.go b/pkg/cmd/podthread.go index 084222e..309b3f6 100644 --- a/pkg/cmd/podthread.go +++ b/pkg/cmd/podthread.go @@ -16,7 +16,7 @@ import ( var podsThreadsList = cli.Command{ Name: "list", - Usage: "**CLI:**", + Usage: "Lists threads in the pod, most recent first. Pass `senders`, `recipients`, or\n`subject` to filter by substring. Filtered requests are served by search, which\ncaps `limit` at 100. For relevance-ranked full-text search, use\n`Search Threads`.", Suggest: true, Flags: []cli.Flag{ &requestflag.Flag[string]{ @@ -75,6 +75,21 @@ var podsThreadsList = cli.Command{ Usage: "Page token for pagination.", QueryPath: "page_token", }, + &requestflag.Flag[any]{ + Name: "recipient", + Usage: "Filter to threads whose recipients contain this value (substring match). Repeatable; all values must match.", + QueryPath: "recipients", + }, + &requestflag.Flag[any]{ + Name: "sender", + Usage: "Filter to threads whose senders contain this value (substring match). Repeatable; all values must match.", + QueryPath: "senders", + }, + &requestflag.Flag[any]{ + Name: "subject", + Usage: "Filter to threads whose subject contains this value (substring match). Repeatable; all values must match.", + QueryPath: "subject", + }, }, Action: handlePodsThreadsList, HideHelpCommand: true, diff --git a/pkg/cmd/podthread_test.go b/pkg/cmd/podthread_test.go index f2c674a..b78b97f 100644 --- a/pkg/cmd/podthread_test.go +++ b/pkg/cmd/podthread_test.go @@ -26,6 +26,9 @@ func TestPodsThreadsList(t *testing.T) { "--label", "[string]", "--limit", "0", "--page-token", "page_token", + "--recipient", "[string]", + "--sender", "[string]", + "--subject", "[string]", ) }) } diff --git a/pkg/cmd/thread.go b/pkg/cmd/thread.go index b9a345d..f65e8fe 100644 --- a/pkg/cmd/thread.go +++ b/pkg/cmd/thread.go @@ -16,7 +16,7 @@ import ( var threadsList = cli.Command{ Name: "list", - Usage: "**CLI:**", + Usage: "Lists threads, most recent first. Pass `senders`, `recipients`, or `subject` to\nfilter by substring. Filtered requests are served by search, which caps `limit`\nat 100. For relevance-ranked full-text search across senders, recipients,\nsubject, and message body, use `Search Threads`.", Suggest: true, Flags: []cli.Flag{ &requestflag.Flag[any]{ @@ -69,6 +69,21 @@ var threadsList = cli.Command{ Usage: "Page token for pagination.", QueryPath: "page_token", }, + &requestflag.Flag[any]{ + Name: "recipient", + Usage: "Filter to threads whose recipients contain this value (substring match). Repeatable; all values must match.", + QueryPath: "recipients", + }, + &requestflag.Flag[any]{ + Name: "sender", + Usage: "Filter to threads whose senders contain this value (substring match). Repeatable; all values must match.", + QueryPath: "senders", + }, + &requestflag.Flag[any]{ + Name: "subject", + Usage: "Filter to threads whose subject contains this value (substring match). Repeatable; all values must match.", + QueryPath: "subject", + }, }, Action: handleThreadsList, HideHelpCommand: true, diff --git a/pkg/cmd/thread_test.go b/pkg/cmd/thread_test.go index b9d55f9..12a7b96 100644 --- a/pkg/cmd/thread_test.go +++ b/pkg/cmd/thread_test.go @@ -25,6 +25,9 @@ func TestThreadsList(t *testing.T) { "--label", "[string]", "--limit", "0", "--page-token", "page_token", + "--recipient", "[string]", + "--sender", "[string]", + "--subject", "[string]", ) }) } diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index d0a0ee8..5f6440b 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -2,4 +2,4 @@ package cmd -const Version = "0.7.12" // x-release-please-version +const Version = "0.7.13" // x-release-please-version diff --git a/pkg/cmd/webhook.go b/pkg/cmd/webhook.go index 0294e1d..9d8b9a6 100644 --- a/pkg/cmd/webhook.go +++ b/pkg/cmd/webhook.go @@ -36,11 +36,6 @@ var webhooksCreate = cli.Command{ Usage: "Client ID of webhook.", BodyPath: "client_id", }, - &requestflag.Flag[any]{ - Name: "inbox-id", - Usage: "Inboxes for which to send events. Maximum 10 per webhook.", - BodyPath: "inbox_ids", - }, &requestflag.Flag[any]{ Name: "pod-id", Usage: "Pods for which to send events. Maximum 10 per webhook.", @@ -62,11 +57,6 @@ var webhooksUpdate = cli.Command{ Required: true, PathParam: "webhook_id", }, - &requestflag.Flag[any]{ - Name: "add-inbox-id", - Usage: "Inbox IDs to subscribe to the webhook.", - BodyPath: "add_inbox_ids", - }, &requestflag.Flag[any]{ Name: "add-pod-id", Usage: "Pod IDs to subscribe to the webhook.", @@ -77,11 +67,6 @@ var webhooksUpdate = cli.Command{ Usage: "When you send a non-empty list, it replaces the webhook's subscribed event types in full (the same\n\"set the list\" behavior as create). It is not a merge or diff: include every event type you want after\nthe update. Sending a one-element array means the webhook will only receive that one type afterward.\nOmit this field or send an empty array to leave event types unchanged. Clearing all types with an empty\nlist is not supported. Subscribing to `message.received.spam`, `message.received.blocked`, or\n`message.received.unauthenticated` requires the matching label permission on the API key.", BodyPath: "event_types", }, - &requestflag.Flag[any]{ - Name: "remove-inbox-id", - Usage: "Inbox IDs to unsubscribe from the webhook.", - BodyPath: "remove_inbox_ids", - }, &requestflag.Flag[any]{ Name: "remove-pod-id", Usage: "Pod IDs to unsubscribe from the webhook.", diff --git a/pkg/cmd/webhook_test.go b/pkg/cmd/webhook_test.go index c5c929b..90f7279 100644 --- a/pkg/cmd/webhook_test.go +++ b/pkg/cmd/webhook_test.go @@ -18,7 +18,6 @@ func TestWebhooksCreate(t *testing.T) { "--event-type", "message.received", "--url", "url", "--client-id", "client_id", - "--inbox-id", "[string]", "--pod-id", "[string]", ) }) @@ -30,8 +29,6 @@ func TestWebhooksCreate(t *testing.T) { " - message.received\n" + "url: url\n" + "client_id: client_id\n" + - "inbox_ids:\n" + - " - string\n" + "pod_ids:\n" + " - string\n") mocktest.TestRunMockTestWithPipeAndFlags( @@ -50,10 +47,8 @@ func TestWebhooksUpdate(t *testing.T) { "--api-key", "string", "webhooks", "update", "--webhook-id", "webhook_id", - "--add-inbox-id", "[string]", "--add-pod-id", "[string]", "--event-type", "[message.received]", - "--remove-inbox-id", "[string]", "--remove-pod-id", "[string]", ) }) @@ -61,14 +56,10 @@ func TestWebhooksUpdate(t *testing.T) { t.Run("piping data", func(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("" + - "add_inbox_ids:\n" + - " - string\n" + "add_pod_ids:\n" + " - string\n" + "event_types:\n" + " - message.received\n" + - "remove_inbox_ids:\n" + - " - string\n" + "remove_pod_ids:\n" + " - string\n") mocktest.TestRunMockTestWithPipeAndFlags(