From 2a0195ef893339e931434cc30db149f45a0479aa Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 02:53:12 +0000 Subject: [PATCH 01/14] chore(internal): codegen related update --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fc4ffb7..4d42343 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/beeper/desktop-api-cli go 1.25 require ( - github.com/beeper/desktop-api-go v0.4.0 + github.com/beeper/desktop-api-go v0.5.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 057802d..c6fed8f 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= -github.com/beeper/desktop-api-go v0.4.0 h1:cSZLj1pSVD7pAdBOwiHkSzpXDoWjzJCRfb7lDtW5POM= -github.com/beeper/desktop-api-go v0.4.0/go.mod h1:y9Mk83OdQWo6ldLTcPyaUPrwjkmvy/3QkhHqZLhU/mA= +github.com/beeper/desktop-api-go v0.5.0 h1:0Myrz8eop5dC3/QseUrbYVIyWkHPGLyU47/lffw/kT4= +github.com/beeper/desktop-api-go v0.5.0/go.mod h1:y9Mk83OdQWo6ldLTcPyaUPrwjkmvy/3QkhHqZLhU/mA= github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs= github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg= github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU= From 924553222c9f4fcd06bd3c84d8fdeb9e5b6aa81f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 01:45:34 +0000 Subject: [PATCH 02/14] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 004aab8..06ba3c3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-5a8ac7b545c48dc892e5c680303e305254921554dabee848e40a808659dbcf1e.yml openapi_spec_hash: 0103975601aac1445d3a4ef418c5d17a -config_hash: aa49273410d42fb96c5515dbce1f182f +config_hash: bfb432c69dc0a8d273043a3cdd87ffe1 From da3011e4651174a1303910042afff3e055a71b49 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 01:46:51 +0000 Subject: [PATCH 03/14] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 06ba3c3..72a5288 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-5a8ac7b545c48dc892e5c680303e305254921554dabee848e40a808659dbcf1e.yml openapi_spec_hash: 0103975601aac1445d3a4ef418c5d17a -config_hash: bfb432c69dc0a8d273043a3cdd87ffe1 +config_hash: a7eb18d34cd75f7dbffe1940df6b2e9e From c9974925c5d60aa534b8d619e51594cab0d622f0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 03:05:06 +0000 Subject: [PATCH 04/14] fix: fix for test cases with newlines in YAML and better error reporting --- pkg/cmd/flagoptions.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/pkg/cmd/flagoptions.go b/pkg/cmd/flagoptions.go index 6f5bdcb..b11392c 100644 --- a/pkg/cmd/flagoptions.go +++ b/pkg/cmd/flagoptions.go @@ -227,19 +227,20 @@ func flagOptions( if len(pipeData) > 0 { var bodyData any - if err := yaml.Unmarshal(pipeData, &bodyData); err == nil { - if bodyMap, ok := bodyData.(map[string]any); ok { - if flagMap, ok := requestContents.Body.(map[string]any); ok { - maps.Copy(bodyMap, flagMap) - requestContents.Body = bodyMap - } else { - bodyData = requestContents.Body - } - } else if flagMap, ok := requestContents.Body.(map[string]any); ok && len(flagMap) > 0 { - return nil, fmt.Errorf("Cannot merge flags with a body that is not a map: %v", bodyData) + if err := yaml.Unmarshal(pipeData, &bodyData); err != nil { + return nil, fmt.Errorf("Failed to parse piped data as YAML/JSON:\n%w", err) + } + if bodyMap, ok := bodyData.(map[string]any); ok { + if flagMap, ok := requestContents.Body.(map[string]any); ok { + maps.Copy(bodyMap, flagMap) + requestContents.Body = bodyMap } else { - requestContents.Body = bodyData + bodyData = requestContents.Body } + } else if flagMap, ok := requestContents.Body.(map[string]any); ok && len(flagMap) > 0 { + return nil, fmt.Errorf("Cannot merge flags with a body that is not a map: %v", bodyData) + } else { + requestContents.Body = bodyData } } } From 0770d3ad509df79341bb1067de910a4ececdc07e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 17:22:06 +0000 Subject: [PATCH 05/14] feat(api): manual updates --- .stats.yml | 2 +- README.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 72a5288..5dbc3d6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-5a8ac7b545c48dc892e5c680303e305254921554dabee848e40a808659dbcf1e.yml openapi_spec_hash: 0103975601aac1445d3a4ef418c5d17a -config_hash: a7eb18d34cd75f7dbffe1940df6b2e9e +config_hash: 6fc4359a793fc3fc9ac01712b5ef8c0d diff --git a/README.md b/README.md index 24b5143..09e97fb 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ The official CLI for the [Beeper Desktop REST API](https://developers.beeper.com/desktop-api/). +It is generated with [Stainless](https://www.stainless.com/). + ## Installation From 5d05113d217d66521b1a1dcff45a92a4f71fc5d6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 14:36:18 +0000 Subject: [PATCH 06/14] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 5dbc3d6..2b39be6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-5a8ac7b545c48dc892e5c680303e305254921554dabee848e40a808659dbcf1e.yml openapi_spec_hash: 0103975601aac1445d3a4ef418c5d17a -config_hash: 6fc4359a793fc3fc9ac01712b5ef8c0d +config_hash: ca148af6be59ec54295b2c5f852a38d1 From 923b0ebdeeafe5aa17f416651d82ee20c643fd16 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 03:13:41 +0000 Subject: [PATCH 07/14] fix: only set client options when the corresponding CLI flag or env var is explicitly set --- pkg/cmd/cmdutil.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/cmd/cmdutil.go b/pkg/cmd/cmdutil.go index d5bea76..2b731fa 100644 --- a/pkg/cmd/cmdutil.go +++ b/pkg/cmd/cmdutil.go @@ -36,7 +36,9 @@ func getDefaultRequestOptions(cmd *cli.Command) []option.RequestOption { option.WithHeader("X-Stainless-Package-Version", Version), option.WithHeader("X-Stainless-Runtime", "cli"), option.WithHeader("X-Stainless-CLI-Command", cmd.FullName()), - option.WithAccessToken(cmd.String("access-token")), + } + if cmd.IsSet("access-token") { + opts = append(opts, option.WithAccessToken(cmd.String("access-token"))) } // Override base URL if the --base-url flag is provided From e7e84887ed26fb2de032a1960ea881fb15c7b3c4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 03:07:45 +0000 Subject: [PATCH 08/14] fix: improved workflow for developing on branches --- .github/actions/setup-go/action.yml | 27 +++++++++++++++++++++++ .github/workflows/ci.yml | 33 +++++++++++++++++++++-------- scripts/bootstrap | 3 +-- scripts/build | 5 ++++- scripts/link | 15 ++++++------- scripts/lint | 5 ++++- scripts/run | 5 ++++- scripts/test | 3 +++ 8 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 .github/actions/setup-go/action.yml diff --git a/.github/actions/setup-go/action.yml b/.github/actions/setup-go/action.yml new file mode 100644 index 0000000..d5a264f --- /dev/null +++ b/.github/actions/setup-go/action.yml @@ -0,0 +1,27 @@ +name: Setup Go +description: 'Sets up Go environment with private modules' +inputs: + stainless-api-key: + required: true + description: the value of the STAINLESS_API_KEY secret +runs: + using: composite + steps: + - uses: stainless-api/retrieve-github-access-token@v1 + id: get_token + with: + repo: stainless-sdks/beeper-desktop-api-go + stainless-api-key: ${{ inputs.stainless-api-key }} + + - name: Configure Git for access to the Go SDK's staging repo + shell: bash + run: git config --global url."https://x-access-token:${{ steps.get_token.outputs.github_access_token }}@github.com/stainless-sdks/beeper-desktop-api-go".insteadOf "https://github.com/stainless-sdks/beeper-desktop-api-go" + + - name: Setup go + uses: actions/setup-go@v5 + with: + go-version-file: ./go.mod + + - name: Bootstrap + shell: bash + run: ./scripts/bootstrap diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2cca0d4..62b5246 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,9 @@ on: - 'stl-preview-head/**' - 'stl-preview-base/**' +env: + GOPRIVATE: github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go + jobs: lint: timeout-minutes: 10 @@ -22,10 +25,14 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Setup go - uses: actions/setup-go@v5 + - uses: ./.github/actions/setup-go with: - go-version-file: ./go.mod + stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} + + - name: Link staging branch + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' + run: | + ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' - name: Bootstrap run: ./scripts/bootstrap @@ -44,10 +51,14 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Setup go - uses: actions/setup-go@v5 + - uses: ./.github/actions/setup-go with: - go-version-file: ./go.mod + stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} + + - name: Link staging branch + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' + run: | + ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' - name: Bootstrap run: ./scripts/bootstrap @@ -87,10 +98,14 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Setup go - uses: actions/setup-go@v5 + - uses: ./.github/actions/setup-go with: - go-version-file: ./go.mod + stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} + + - name: Link staging branch + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' + run: | + ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' - name: Bootstrap run: ./scripts/bootstrap diff --git a/scripts/bootstrap b/scripts/bootstrap index d94c7d1..9ebb7d3 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -18,6 +18,5 @@ if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] echo } fi - echo "==> Installing Go dependencies…" -go mod tidy +go mod tidy -e || true diff --git a/scripts/build b/scripts/build index f81d546..7eb0308 100755 --- a/scripts/build +++ b/scripts/build @@ -1,8 +1,11 @@ #!/usr/bin/env bash -set -e +set -euo pipefail cd "$(dirname "$0")/.." +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" + echo "==> Building beeper-desktop-cli" go build ./cmd/beeper-desktop-cli diff --git a/scripts/link b/scripts/link index 72a1247..2da9715 100755 --- a/scripts/link +++ b/scripts/link @@ -1,16 +1,13 @@ #!/usr/bin/env bash -set -e +set -euo pipefail cd "$(dirname "$0")/.." -if [[ -n "$1" ]]; then - LOCAL_GO="$1" - shift -else - LOCAL_GO=../beeperdesktop-go -fi +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" -echo "==> Linking with local directory" +REPLACEMENT="${1:-"../beeperdesktop-go"}" +echo "==> Replacing Go SDK with $REPLACEMENT" +go mod edit -replace github.com/beeper/desktop-api-go="$REPLACEMENT" go mod tidy -e -go mod edit -replace github.com/beeper/desktop-api-go="$LOCAL_GO" diff --git a/scripts/lint b/scripts/lint index fa7ba1f..bfcb7b6 100755 --- a/scripts/lint +++ b/scripts/lint @@ -1,8 +1,11 @@ #!/usr/bin/env bash -set -e +set -euo pipefail cd "$(dirname "$0")/.." +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" + echo "==> Running Go build" go build ./... diff --git a/scripts/run b/scripts/run index b18ccb7..5cfec5f 100755 --- a/scripts/run +++ b/scripts/run @@ -1,7 +1,10 @@ #!/usr/bin/env bash -set -e +set -euo pipefail cd "$(dirname "$0")/.." +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" + go run ./cmd/beeper-desktop-cli "$@" diff --git a/scripts/test b/scripts/test index 7383fc5..7d37fe0 100755 --- a/scripts/test +++ b/scripts/test @@ -4,6 +4,9 @@ set -euo pipefail cd "$(dirname "$0")/.." +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" + RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' From 9100cf6e1ee5b4e7c7bcb262636fe3f458224cd4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 03:18:01 +0000 Subject: [PATCH 09/14] fix: better support passing client args in any position --- internal/requestflag/requestflag.go | 8 ++++++++ pkg/cmd/account_test.go | 3 ++- pkg/cmd/accountcontact_test.go | 6 ++++-- pkg/cmd/asset_test.go | 21 ++++++++++++++------- pkg/cmd/beeperdesktopapi_test.go | 9 ++++++--- pkg/cmd/chat_test.go | 24 ++++++++++++++++-------- pkg/cmd/chatmessagereaction_test.go | 9 ++++++--- pkg/cmd/chatreminder_test.go | 12 ++++++++---- pkg/cmd/info_test.go | 3 ++- pkg/cmd/message_test.go | 21 ++++++++++++++------- 10 files changed, 80 insertions(+), 36 deletions(-) diff --git a/internal/requestflag/requestflag.go b/internal/requestflag/requestflag.go index 986afed..21a8a69 100644 --- a/internal/requestflag/requestflag.go +++ b/internal/requestflag/requestflag.go @@ -374,6 +374,14 @@ func (f *Flag[T]) Count() int { return f.count } +// Implementation for the cli.LocalFlag interface +var _ cli.LocalFlag = (*Flag[any])(nil) // Type assertion to ensure interface compliance + +func (f Flag[T]) IsLocal() bool { + // By default, all request flags are local, i.e. can be provided at any part of the CLI command. + return true +} + // cliValue is a generic implementation of cli.Value for common types type cliValue[ T []any | []map[string]any | []DateTimeValue | []DateValue | []TimeValue | []string | []float64 | diff --git a/pkg/cmd/account_test.go b/pkg/cmd/account_test.go index 02c4f22..cc8844f 100644 --- a/pkg/cmd/account_test.go +++ b/pkg/cmd/account_test.go @@ -11,8 +11,9 @@ import ( func TestAccountsList(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "accounts", "list", + t, "--access-token", "string", + "accounts", "list", ) }) } diff --git a/pkg/cmd/accountcontact_test.go b/pkg/cmd/accountcontact_test.go index 6bc7110..36d7908 100644 --- a/pkg/cmd/accountcontact_test.go +++ b/pkg/cmd/accountcontact_test.go @@ -11,8 +11,9 @@ import ( func TestAccountsContactsList(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "accounts:contacts", "list", + t, "--access-token", "string", + "accounts:contacts", "list", "--max-items", "10", "--account-id", "accountID", "--cursor", "1725489123456|c29tZUltc2dQYWdl", @@ -26,8 +27,9 @@ func TestAccountsContactsList(t *testing.T) { func TestAccountsContactsSearch(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "accounts:contacts", "search", + t, "--access-token", "string", + "accounts:contacts", "search", "--account-id", "accountID", "--query", "x", ) diff --git a/pkg/cmd/asset_test.go b/pkg/cmd/asset_test.go index 4ed84d8..2ce574c 100644 --- a/pkg/cmd/asset_test.go +++ b/pkg/cmd/asset_test.go @@ -11,8 +11,9 @@ import ( func TestAssetsDownload(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "assets", "download", + t, "--access-token", "string", + "assets", "download", "--url", "mxc://example.org/Q4x9CqGz1pB3Oa6XgJ", ) }) @@ -21,8 +22,9 @@ func TestAssetsDownload(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("url: mxc://example.org/Q4x9CqGz1pB3Oa6XgJ") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "assets", "download", + t, pipeData, "--access-token", "string", + "assets", "download", ) }) } @@ -30,8 +32,9 @@ func TestAssetsDownload(t *testing.T) { func TestAssetsServe(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "assets", "serve", + t, "--access-token", "string", + "assets", "serve", "--url", "x", ) }) @@ -40,8 +43,9 @@ func TestAssetsServe(t *testing.T) { func TestAssetsUpload(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "assets", "upload", + t, "--access-token", "string", + "assets", "upload", "--file", "Example data", "--file-name", "fileName", "--mime-type", "mimeType", @@ -55,8 +59,9 @@ func TestAssetsUpload(t *testing.T) { "fileName: fileName\n" + "mimeType: mimeType\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "assets", "upload", + t, pipeData, "--access-token", "string", + "assets", "upload", ) }) } @@ -64,8 +69,9 @@ func TestAssetsUpload(t *testing.T) { func TestAssetsUploadBase64(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "assets", "upload-base64", + t, "--access-token", "string", + "assets", "upload-base64", "--content", "x", "--file-name", "fileName", "--mime-type", "mimeType", @@ -79,8 +85,9 @@ func TestAssetsUploadBase64(t *testing.T) { "fileName: fileName\n" + "mimeType: mimeType\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "assets", "upload-base64", + t, pipeData, "--access-token", "string", + "assets", "upload-base64", ) }) } diff --git a/pkg/cmd/beeperdesktopapi_test.go b/pkg/cmd/beeperdesktopapi_test.go index a418bd7..f07d043 100644 --- a/pkg/cmd/beeperdesktopapi_test.go +++ b/pkg/cmd/beeperdesktopapi_test.go @@ -11,8 +11,9 @@ import ( func TestFocus(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "focus", + t, "--access-token", "string", + "focus", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--draft-attachment-path", "draftAttachmentPath", "--draft-text", "draftText", @@ -28,8 +29,9 @@ func TestFocus(t *testing.T) { "draftText: draftText\n" + "messageID: messageID\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "focus", + t, pipeData, "--access-token", "string", + "focus", ) }) } @@ -37,8 +39,9 @@ func TestFocus(t *testing.T) { func TestSearch(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "search", + t, "--access-token", "string", + "search", "--query", "x", ) }) diff --git a/pkg/cmd/chat_test.go b/pkg/cmd/chat_test.go index f6be069..ff041f7 100644 --- a/pkg/cmd/chat_test.go +++ b/pkg/cmd/chat_test.go @@ -12,8 +12,9 @@ import ( func TestChatsCreate(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "create", + t, "--access-token", "string", + "chats", "create", "--account-id", "accountID", "--allow-invite=true", "--message-text", "messageText", @@ -31,8 +32,9 @@ func TestChatsCreate(t *testing.T) { // Alternative argument passing style using inner flags mocktest.TestRunMockTestWithFlags( - t, "chats", "create", + t, "--access-token", "string", + "chats", "create", "--account-id", "accountID", "--allow-invite=true", "--message-text", "messageText", @@ -66,8 +68,9 @@ func TestChatsCreate(t *testing.T) { " phoneNumber: phoneNumber\n" + " username: username\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "chats", "create", + t, pipeData, "--access-token", "string", + "chats", "create", ) }) } @@ -75,8 +78,9 @@ func TestChatsCreate(t *testing.T) { func TestChatsRetrieve(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "retrieve", + t, "--access-token", "string", + "chats", "retrieve", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--max-participant-count", "50", ) @@ -86,8 +90,9 @@ func TestChatsRetrieve(t *testing.T) { func TestChatsList(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "list", + t, "--access-token", "string", + "chats", "list", "--max-items", "10", "--account-id", "local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc", "--account-id", "local-instagram_ba_eRfQMmnSNy_p7Ih7HL7RduRpKFU", @@ -100,8 +105,9 @@ func TestChatsList(t *testing.T) { func TestChatsArchive(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "archive", + t, "--access-token", "string", + "chats", "archive", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--archived=true", ) @@ -111,8 +117,9 @@ func TestChatsArchive(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("archived: true") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "chats", "archive", + t, pipeData, "--access-token", "string", + "chats", "archive", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", ) }) @@ -121,8 +128,9 @@ func TestChatsArchive(t *testing.T) { func TestChatsSearch(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "search", + t, "--access-token", "string", + "chats", "search", "--max-items", "10", "--account-id", "local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc", "--account-id", "local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI", diff --git a/pkg/cmd/chatmessagereaction_test.go b/pkg/cmd/chatmessagereaction_test.go index 7a26ed2..74168cd 100644 --- a/pkg/cmd/chatmessagereaction_test.go +++ b/pkg/cmd/chatmessagereaction_test.go @@ -11,8 +11,9 @@ import ( func TestChatsMessagesReactionsDelete(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats:messages:reactions", "delete", + t, "--access-token", "string", + "chats:messages:reactions", "delete", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", "--reaction-key", "x", @@ -23,8 +24,9 @@ func TestChatsMessagesReactionsDelete(t *testing.T) { func TestChatsMessagesReactionsAdd(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats:messages:reactions", "add", + t, "--access-token", "string", + "chats:messages:reactions", "add", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", "--reaction-key", "x", @@ -38,8 +40,9 @@ func TestChatsMessagesReactionsAdd(t *testing.T) { "reactionKey: x\n" + "transactionID: transactionID\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "chats:messages:reactions", "add", + t, pipeData, "--access-token", "string", + "chats:messages:reactions", "add", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", ) diff --git a/pkg/cmd/chatreminder_test.go b/pkg/cmd/chatreminder_test.go index eeaaaec..84f08fb 100644 --- a/pkg/cmd/chatreminder_test.go +++ b/pkg/cmd/chatreminder_test.go @@ -12,8 +12,9 @@ import ( func TestChatsRemindersCreate(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats:reminders", "create", + t, "--access-token", "string", + "chats:reminders", "create", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--reminder", "{remindAtMs: 0, dismissOnIncomingMessage: true}", ) @@ -25,8 +26,9 @@ func TestChatsRemindersCreate(t *testing.T) { // Alternative argument passing style using inner flags mocktest.TestRunMockTestWithFlags( - t, "chats:reminders", "create", + t, "--access-token", "string", + "chats:reminders", "create", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--reminder.remind-at-ms", "0", "--reminder.dismiss-on-incoming-message=true", @@ -40,8 +42,9 @@ func TestChatsRemindersCreate(t *testing.T) { " remindAtMs: 0\n" + " dismissOnIncomingMessage: true\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "chats:reminders", "create", + t, pipeData, "--access-token", "string", + "chats:reminders", "create", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", ) }) @@ -50,8 +53,9 @@ func TestChatsRemindersCreate(t *testing.T) { func TestChatsRemindersDelete(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats:reminders", "delete", + t, "--access-token", "string", + "chats:reminders", "delete", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", ) }) diff --git a/pkg/cmd/info_test.go b/pkg/cmd/info_test.go index 3ce4d47..507d04e 100644 --- a/pkg/cmd/info_test.go +++ b/pkg/cmd/info_test.go @@ -11,8 +11,9 @@ import ( func TestInfoRetrieve(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "info", "retrieve", + t, "--access-token", "string", + "info", "retrieve", ) }) } diff --git a/pkg/cmd/message_test.go b/pkg/cmd/message_test.go index 36eddf3..11fe9a2 100644 --- a/pkg/cmd/message_test.go +++ b/pkg/cmd/message_test.go @@ -12,8 +12,9 @@ import ( func TestMessagesUpdate(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "messages", "update", + t, "--access-token", "string", + "messages", "update", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", "--text", "x", @@ -24,8 +25,9 @@ func TestMessagesUpdate(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("text: x") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "messages", "update", + t, pipeData, "--access-token", "string", + "messages", "update", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", ) @@ -35,8 +37,9 @@ func TestMessagesUpdate(t *testing.T) { func TestMessagesList(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "messages", "list", + t, "--access-token", "string", + "messages", "list", "--max-items", "10", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--cursor", "1725489123456|c29tZUltc2dQYWdl", @@ -48,8 +51,9 @@ func TestMessagesList(t *testing.T) { func TestMessagesSearch(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "messages", "search", + t, "--access-token", "string", + "messages", "search", "--max-items", "10", "--account-id", "local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc", "--account-id", "local-instagram_ba_eRfQMmnSNy_p7Ih7HL7RduRpKFU", @@ -73,8 +77,9 @@ func TestMessagesSearch(t *testing.T) { func TestMessagesSend(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "messages", "send", + t, "--access-token", "string", + "messages", "send", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--attachment", "{uploadID: uploadID, duration: 0, fileName: fileName, mimeType: mimeType, size: {height: 0, width: 0}, type: gif}", "--reply-to-message-id", "replyToMessageID", @@ -88,8 +93,9 @@ func TestMessagesSend(t *testing.T) { // Alternative argument passing style using inner flags mocktest.TestRunMockTestWithFlags( - t, "messages", "send", + t, "--access-token", "string", + "messages", "send", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--attachment.upload-id", "uploadID", "--attachment.duration", "0", @@ -117,8 +123,9 @@ func TestMessagesSend(t *testing.T) { "replyToMessageID: replyToMessageID\n" + "text: text\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "messages", "send", + t, pipeData, "--access-token", "string", + "messages", "send", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", ) }) From f38af96666a55ffd4014c4f6190f5807df8b740e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 03:37:21 +0000 Subject: [PATCH 10/14] fix: no longer require an API key when building on production repos --- .github/actions/setup-go/action.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/actions/setup-go/action.yml b/.github/actions/setup-go/action.yml index d5a264f..480f40f 100644 --- a/.github/actions/setup-go/action.yml +++ b/.github/actions/setup-go/action.yml @@ -2,18 +2,20 @@ name: Setup Go description: 'Sets up Go environment with private modules' inputs: stainless-api-key: - required: true + required: false description: the value of the STAINLESS_API_KEY secret runs: using: composite steps: - uses: stainless-api/retrieve-github-access-token@v1 + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' id: get_token with: repo: stainless-sdks/beeper-desktop-api-go stainless-api-key: ${{ inputs.stainless-api-key }} - name: Configure Git for access to the Go SDK's staging repo + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' shell: bash run: git config --global url."https://x-access-token:${{ steps.get_token.outputs.github_access_token }}@github.com/stainless-sdks/beeper-desktop-api-go".insteadOf "https://github.com/stainless-sdks/beeper-desktop-api-go" From e727f07b8f5f6792c0e67fd6a048cfdd91ab3ba3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 03:38:35 +0000 Subject: [PATCH 11/14] chore(internal): tweak CI branches --- .github/workflows/ci.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62b5246..5277a9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,14 @@ name: CI on: push: - branches-ignore: - - 'generated' - - 'codegen/**' - - 'integrated/**' - - 'stl-preview-head/**' - - 'stl-preview-base/**' + branches: + - '**' + - '!integrated/**' + - '!stl-preview-head/**' + - '!stl-preview-base/**' + - '!generated' + - '!codegen/**' + - 'codegen/stl/**' pull_request: branches-ignore: - 'stl-preview-head/**' From 040b5552613ef61130225e1f6cf81ab213d3a4a9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 02:49:34 +0000 Subject: [PATCH 12/14] fix: avoid reading from stdin unless request body is form encoded or json --- pkg/cmd/flagoptions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cmd/flagoptions.go b/pkg/cmd/flagoptions.go index b11392c..4a39cd0 100644 --- a/pkg/cmd/flagoptions.go +++ b/pkg/cmd/flagoptions.go @@ -219,7 +219,7 @@ func flagOptions( requestContents := requestflag.ExtractRequestContents(cmd) - if bodyType != ApplicationOctetStream && isInputPiped() && !ignoreStdin { + if (bodyType == MultipartFormEncoded || bodyType == ApplicationJSON) && !ignoreStdin && isInputPiped() { pipeData, err := io.ReadAll(os.Stdin) if err != nil { return nil, err From c5964a17c6203b0de179d6c73c62665c8c33e364 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 02:18:19 +0000 Subject: [PATCH 13/14] fix: improve linking behavior when developing on a branch not in the Go SDK --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5277a9a..2742613 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: - name: Link staging branch if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' run: | - ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' + ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' || true - name: Bootstrap run: ./scripts/bootstrap @@ -60,7 +60,7 @@ jobs: - name: Link staging branch if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' run: | - ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' + ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' || true - name: Bootstrap run: ./scripts/bootstrap @@ -107,7 +107,7 @@ jobs: - name: Link staging branch if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' run: | - ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' + ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' || true - name: Bootstrap run: ./scripts/bootstrap From 840726b7086eb6c771781ae775fc5717910506ec Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 02:18:35 +0000 Subject: [PATCH 14/14] release: 0.3.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 25 +++++++++++++++++++++++++ pkg/cmd/version.go | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 10f3091..6b7b74c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.2.0" + ".": "0.3.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index c8f26bc..eb19885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## 0.3.0 (2026-03-19) + +Full Changelog: [v0.2.0...v0.3.0](https://github.com/beeper/desktop-api-cli/compare/v0.2.0...v0.3.0) + +### Features + +* **api:** manual updates ([0770d3a](https://github.com/beeper/desktop-api-cli/commit/0770d3ad509df79341bb1067de910a4ececdc07e)) + + +### Bug Fixes + +* avoid reading from stdin unless request body is form encoded or json ([040b555](https://github.com/beeper/desktop-api-cli/commit/040b5552613ef61130225e1f6cf81ab213d3a4a9)) +* better support passing client args in any position ([9100cf6](https://github.com/beeper/desktop-api-cli/commit/9100cf6e1ee5b4e7c7bcb262636fe3f458224cd4)) +* fix for test cases with newlines in YAML and better error reporting ([c997492](https://github.com/beeper/desktop-api-cli/commit/c9974925c5d60aa534b8d619e51594cab0d622f0)) +* improve linking behavior when developing on a branch not in the Go SDK ([c5964a1](https://github.com/beeper/desktop-api-cli/commit/c5964a17c6203b0de179d6c73c62665c8c33e364)) +* improved workflow for developing on branches ([e7e8488](https://github.com/beeper/desktop-api-cli/commit/e7e84887ed26fb2de032a1960ea881fb15c7b3c4)) +* no longer require an API key when building on production repos ([f38af96](https://github.com/beeper/desktop-api-cli/commit/f38af96666a55ffd4014c4f6190f5807df8b740e)) +* only set client options when the corresponding CLI flag or env var is explicitly set ([923b0eb](https://github.com/beeper/desktop-api-cli/commit/923b0ebdeeafe5aa17f416651d82ee20c643fd16)) + + +### Chores + +* **internal:** codegen related update ([2a0195e](https://github.com/beeper/desktop-api-cli/commit/2a0195ef893339e931434cc30db149f45a0479aa)) +* **internal:** tweak CI branches ([e727f07](https://github.com/beeper/desktop-api-cli/commit/e727f07b8f5f6792c0e67fd6a048cfdd91ab3ba3)) + ## 0.2.0 (2026-03-06) Full Changelog: [v0.1.1...v0.2.0](https://github.com/beeper/desktop-api-cli/compare/v0.1.1...v0.2.0) diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index 10d2893..5266c84 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -2,4 +2,4 @@ package cmd -const Version = "0.2.0" // x-release-please-version +const Version = "0.3.0" // x-release-please-version