diff --git a/.goreleaser.yml b/.goreleaser.yml index 134c665..7d2350c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -67,7 +67,7 @@ snapshot: nfpms: - license: Apache-2.0 - maintainer: + maintainer: contact@agentmail.cc bindir: /usr formats: - apk diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 08b4d2e..ec46183 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.7.13" + ".": "0.7.14" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index d3bc70a..5df686d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 91 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/agentmail/agentmail-af6486aae3ab676a9825da6bd60ea7dad5d76a22c1cc8ba80515767ee774c270.yml +configured_endpoints: 95 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/agentmail/agentmail-710dd939e94b2dbb7a2d7ffae0f5dbc6bab5893c201299f452fcf39e7dbd886c.yml openapi_spec_hash: 4eb49916915aeac5a7897470322459d4 -config_hash: 79c13cf7727d64173933e0d367570632 +config_hash: 8c7283a75ec714092fa5f03087e28a65 diff --git a/CHANGELOG.md b/CHANGELOG.md index b300f73..ecdf208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.7.14 (2026-07-15) + +Full Changelog: [v0.7.13...v0.7.14](https://github.com/agentmail-to/agentmail-cli/compare/v0.7.13...v0.7.14) + +### Features + +* **api:** manual updates ([ea4745a](https://github.com/agentmail-to/agentmail-cli/commit/ea4745a779de5863f6d1a8db10b802c3e0e28414)) + ## 0.7.13 (2026-07-15) Full Changelog: [v0.7.12...v0.7.13](https://github.com/agentmail-to/agentmail-cli/compare/v0.7.12...v0.7.13) diff --git a/SECURITY.md b/SECURITY.md index 92e3ccb..076641f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -18,6 +18,10 @@ before making any information public. If you encounter security issues that are not directly related to SDKs but pertain to the services or products provided by Agentmail, please follow the respective company's security reporting guidelines. +### Agentmail Terms and Policies + +Please contact contact@agentmail.cc for any questions or concerns regarding the security of our services. + --- Thank you for helping us keep the SDKs and systems they interact with secure. diff --git a/go.mod b/go.mod index 63fcca6..aceb44f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/agentmail-to/agentmail-cli go 1.25 require ( - github.com/agentmail-to/agentmail-go v0.15.0 + github.com/agentmail-to/agentmail-go v0.16.0 github.com/charmbracelet/bubbles v0.21.0 github.com/charmbracelet/bubbletea v1.3.6 github.com/charmbracelet/lipgloss v1.1.0 diff --git a/go.sum b/go.sum index 93cad51..b9954b5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/agentmail-to/agentmail-go v0.15.0 h1:K8j9wQqbq+X0lM4UyaDmnMlEzGcQnD/jVOv0DtbnsRw= -github.com/agentmail-to/agentmail-go v0.15.0/go.mod h1:3NrKbeXLQKRgb9gj2bmCoN9WXDTy9y9yacV070xpvDU= +github.com/agentmail-to/agentmail-go v0.16.0 h1:L3FBYX4yXaxReA5GS2wgwrmZpDGFIKHGLmrs30nGjY4= +github.com/agentmail-to/agentmail-go v0.16.0/go.mod h1:3NrKbeXLQKRgb9gj2bmCoN9WXDTy9y9yacV070xpvDU= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 5b65926..2e8851d 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -136,6 +136,7 @@ func init() { &inboxesMessagesGetRaw, &inboxesMessagesReply, &inboxesMessagesReplyAll, + &inboxesMessagesSearch, &inboxesMessagesSend, }, }, @@ -148,6 +149,7 @@ func init() { &inboxesThreadsDelete, &inboxesThreadsGet, &inboxesThreadsGetAttachment, + &inboxesThreadsSearch, }, }, { @@ -227,6 +229,7 @@ func init() { &podsThreadsDelete, &podsThreadsGet, &podsThreadsGetAttachment, + &podsThreadsSearch, }, }, { @@ -324,6 +327,7 @@ func init() { &threadsDelete, &threadsGet, &threadsGetAttachment, + &threadsSearch, }, }, { diff --git a/pkg/cmd/inboxmessage.go b/pkg/cmd/inboxmessage.go index eb4c4b8..5de6486 100644 --- a/pkg/cmd/inboxmessage.go +++ b/pkg/cmd/inboxmessage.go @@ -503,6 +503,48 @@ var inboxesMessagesReplyAll = requestflag.WithInnerFlags(cli.Command{ }, }) +var inboxesMessagesSearch = cli.Command{ + Name: "search", + Usage: "Full-text search across messages in the inbox, ranked by relevance. The query is\nmatched against the sender, recipients, and subject (substring) and the message\nbody (tokenized full text). Spam, trash, blocked, and unauthenticated messages\nare always excluded. `limit` cannot exceed 100.", + Suggest: true, + Flags: []cli.Flag{ + &requestflag.Flag[string]{ + Name: "inbox-id", + Usage: "The ID of the inbox.", + Required: true, + PathParam: "inbox_id", + }, + &requestflag.Flag[string]{ + Name: "q", + Usage: "Full-text search query. Matched against the sender, recipients, and\nsubject (substring) and the message body (tokenized full text).", + Required: true, + QueryPath: "q", + }, + &requestflag.Flag[any]{ + Name: "after", + Usage: "Timestamp after which to filter by.", + QueryPath: "after", + }, + &requestflag.Flag[any]{ + Name: "before", + Usage: "Timestamp before which to filter by.", + QueryPath: "before", + }, + &requestflag.Flag[*int64]{ + Name: "limit", + Usage: "Limit of number of items returned.", + QueryPath: "limit", + }, + &requestflag.Flag[*string]{ + Name: "page-token", + Usage: "Page token for pagination.", + QueryPath: "page_token", + }, + }, + Action: handleInboxesMessagesSearch, + HideHelpCommand: true, +} + var inboxesMessagesSend = requestflag.WithInnerFlags(cli.Command{ Name: "send", Usage: "**CLI:**", @@ -1011,6 +1053,55 @@ func handleInboxesMessagesReplyAll(ctx context.Context, cmd *cli.Command) error }) } +func handleInboxesMessagesSearch(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.InboxMessageSearchParams{} + + var res []byte + options = append(options, option.WithResponseBodyInto(&res)) + _, err = client.Inboxes.Messages.Search( + 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:messages search", + Transform: transform, + }) +} + func handleInboxesMessagesSend(ctx context.Context, cmd *cli.Command) error { client := agentmail.NewClient(getDefaultRequestOptions(cmd)...) unusedArgs := cmd.Args().Slice() diff --git a/pkg/cmd/inboxmessage_test.go b/pkg/cmd/inboxmessage_test.go index 75c86bd..de21c6d 100644 --- a/pkg/cmd/inboxmessage_test.go +++ b/pkg/cmd/inboxmessage_test.go @@ -337,6 +337,23 @@ func TestInboxesMessagesReplyAll(t *testing.T) { }) } +func TestInboxesMessagesSearch(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:messages", "search", + "--inbox-id", "inbox_id", + "--q", "q", + "--after", "'2019-12-27T18:11:19.117Z'", + "--before", "'2019-12-27T18:11:19.117Z'", + "--limit", "0", + "--page-token", "page_token", + ) + }) +} + func TestInboxesMessagesSend(t *testing.T) { t.Skip("Mock server tests are disabled") t.Run("regular flags", func(t *testing.T) { diff --git a/pkg/cmd/inboxthread.go b/pkg/cmd/inboxthread.go index dd00063..a95892e 100644 --- a/pkg/cmd/inboxthread.go +++ b/pkg/cmd/inboxthread.go @@ -167,6 +167,48 @@ var inboxesThreadsGetAttachment = cli.Command{ HideHelpCommand: true, } +var inboxesThreadsSearch = cli.Command{ + Name: "search", + Usage: "Full-text search across threads in the inbox, ranked by relevance. The query is\nmatched against senders, recipients, and subject (substring) and the message\nbody (tokenized full text). Spam, trash, blocked, and unauthenticated threads\nare always excluded. `limit` cannot exceed 100.", + Suggest: true, + Flags: []cli.Flag{ + &requestflag.Flag[string]{ + Name: "inbox-id", + Usage: "The ID of the inbox.", + Required: true, + PathParam: "inbox_id", + }, + &requestflag.Flag[string]{ + Name: "q", + Usage: "Full-text search query. Matched against the sender, recipients, and\nsubject (substring) and the message body (tokenized full text).", + Required: true, + QueryPath: "q", + }, + &requestflag.Flag[any]{ + Name: "after", + Usage: "Timestamp after which to filter by.", + QueryPath: "after", + }, + &requestflag.Flag[any]{ + Name: "before", + Usage: "Timestamp before which to filter by.", + QueryPath: "before", + }, + &requestflag.Flag[*int64]{ + Name: "limit", + Usage: "Limit of number of items returned.", + QueryPath: "limit", + }, + &requestflag.Flag[*string]{ + Name: "page-token", + Usage: "Page token for pagination.", + QueryPath: "page_token", + }, + }, + Action: handleInboxesThreadsSearch, + HideHelpCommand: true, +} + func handleInboxesThreadsList(ctx context.Context, cmd *cli.Command) error { client := agentmail.NewClient(getDefaultRequestOptions(cmd)...) unusedArgs := cmd.Args().Slice() @@ -352,3 +394,52 @@ func handleInboxesThreadsGetAttachment(ctx context.Context, cmd *cli.Command) er Transform: transform, }) } + +func handleInboxesThreadsSearch(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.InboxThreadSearchParams{} + + var res []byte + options = append(options, option.WithResponseBodyInto(&res)) + _, err = client.Inboxes.Threads.Search( + 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:threads search", + Transform: transform, + }) +} diff --git a/pkg/cmd/inboxthread_test.go b/pkg/cmd/inboxthread_test.go index 8c9356b..2662624 100644 --- a/pkg/cmd/inboxthread_test.go +++ b/pkg/cmd/inboxthread_test.go @@ -72,3 +72,20 @@ func TestInboxesThreadsGetAttachment(t *testing.T) { ) }) } + +func TestInboxesThreadsSearch(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:threads", "search", + "--inbox-id", "inbox_id", + "--q", "q", + "--after", "'2019-12-27T18:11:19.117Z'", + "--before", "'2019-12-27T18:11:19.117Z'", + "--limit", "0", + "--page-token", "page_token", + ) + }) +} diff --git a/pkg/cmd/podthread.go b/pkg/cmd/podthread.go index 392a64f..548f1fd 100644 --- a/pkg/cmd/podthread.go +++ b/pkg/cmd/podthread.go @@ -167,6 +167,48 @@ var podsThreadsGetAttachment = cli.Command{ HideHelpCommand: true, } +var podsThreadsSearch = cli.Command{ + Name: "search", + Usage: "Full-text search across threads in the pod, ranked by relevance. The query is\nmatched against senders, recipients, and subject (substring) and the message\nbody (tokenized full text). Spam, trash, blocked, and unauthenticated threads\nare always excluded. `limit` cannot exceed 100.", + Suggest: true, + Flags: []cli.Flag{ + &requestflag.Flag[string]{ + Name: "pod-id", + Usage: "ID of pod.", + Required: true, + PathParam: "pod_id", + }, + &requestflag.Flag[string]{ + Name: "q", + Usage: "Full-text search query. Matched against the sender, recipients, and\nsubject (substring) and the message body (tokenized full text).", + Required: true, + QueryPath: "q", + }, + &requestflag.Flag[any]{ + Name: "after", + Usage: "Timestamp after which to filter by.", + QueryPath: "after", + }, + &requestflag.Flag[any]{ + Name: "before", + Usage: "Timestamp before which to filter by.", + QueryPath: "before", + }, + &requestflag.Flag[*int64]{ + Name: "limit", + Usage: "Limit of number of items returned.", + QueryPath: "limit", + }, + &requestflag.Flag[*string]{ + Name: "page-token", + Usage: "Page token for pagination.", + QueryPath: "page_token", + }, + }, + Action: handlePodsThreadsSearch, + HideHelpCommand: true, +} + func handlePodsThreadsList(ctx context.Context, cmd *cli.Command) error { client := agentmail.NewClient(getDefaultRequestOptions(cmd)...) unusedArgs := cmd.Args().Slice() @@ -352,3 +394,52 @@ func handlePodsThreadsGetAttachment(ctx context.Context, cmd *cli.Command) error Transform: transform, }) } + +func handlePodsThreadsSearch(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.PodThreadSearchParams{} + + var res []byte + options = append(options, option.WithResponseBodyInto(&res)) + _, err = client.Pods.Threads.Search( + 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:threads search", + Transform: transform, + }) +} diff --git a/pkg/cmd/podthread_test.go b/pkg/cmd/podthread_test.go index ec839f9..d9849b6 100644 --- a/pkg/cmd/podthread_test.go +++ b/pkg/cmd/podthread_test.go @@ -72,3 +72,20 @@ func TestPodsThreadsGetAttachment(t *testing.T) { ) }) } + +func TestPodsThreadsSearch(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:threads", "search", + "--pod-id", "pod_id", + "--q", "q", + "--after", "'2019-12-27T18:11:19.117Z'", + "--before", "'2019-12-27T18:11:19.117Z'", + "--limit", "0", + "--page-token", "page_token", + ) + }) +} diff --git a/pkg/cmd/thread.go b/pkg/cmd/thread.go index 27d7d9d..787543e 100644 --- a/pkg/cmd/thread.go +++ b/pkg/cmd/thread.go @@ -143,6 +143,42 @@ var threadsGetAttachment = cli.Command{ HideHelpCommand: true, } +var threadsSearch = cli.Command{ + Name: "search", + Usage: "Full-text search across threads in the organization, ranked by relevance. The\nquery is matched against senders, recipients, and subject (substring) and the\nmessage body (tokenized full text). Spam, trash, blocked, and unauthenticated\nthreads are always excluded. `limit` cannot exceed 100.", + Suggest: true, + Flags: []cli.Flag{ + &requestflag.Flag[string]{ + Name: "q", + Usage: "Full-text search query. Matched against the sender, recipients, and\nsubject (substring) and the message body (tokenized full text).", + Required: true, + QueryPath: "q", + }, + &requestflag.Flag[any]{ + Name: "after", + Usage: "Timestamp after which to filter by.", + QueryPath: "after", + }, + &requestflag.Flag[any]{ + Name: "before", + Usage: "Timestamp before which to filter by.", + QueryPath: "before", + }, + &requestflag.Flag[*int64]{ + Name: "limit", + Usage: "Limit of number of items returned.", + QueryPath: "limit", + }, + &requestflag.Flag[*string]{ + Name: "page-token", + Usage: "Page token for pagination.", + QueryPath: "page_token", + }, + }, + Action: handleThreadsSearch, + HideHelpCommand: true, +} + func handleThreadsList(ctx context.Context, cmd *cli.Command) error { client := agentmail.NewClient(getDefaultRequestOptions(cmd)...) unusedArgs := cmd.Args().Slice() @@ -301,3 +337,44 @@ func handleThreadsGetAttachment(ctx context.Context, cmd *cli.Command) error { Transform: transform, }) } + +func handleThreadsSearch(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.ThreadSearchParams{} + + var res []byte + options = append(options, option.WithResponseBodyInto(&res)) + _, err = client.Threads.Search(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: "threads search", + Transform: transform, + }) +} diff --git a/pkg/cmd/thread_test.go b/pkg/cmd/thread_test.go index bec51ca..5d85452 100644 --- a/pkg/cmd/thread_test.go +++ b/pkg/cmd/thread_test.go @@ -68,3 +68,19 @@ func TestThreadsGetAttachment(t *testing.T) { ) }) } + +func TestThreadsSearch(t *testing.T) { + t.Skip("Mock server tests are disabled") + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, + "--api-key", "string", + "threads", "search", + "--q", "q", + "--after", "'2019-12-27T18:11:19.117Z'", + "--before", "'2019-12-27T18:11:19.117Z'", + "--limit", "0", + "--page-token", "page_token", + ) + }) +} diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index 5f6440b..6e914c7 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -2,4 +2,4 @@ package cmd -const Version = "0.7.13" // x-release-please-version +const Version = "0.7.14" // x-release-please-version