From 495de9e16c859e629d03b855e3a65a5cf8850267 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 17:59:40 +0000 Subject: [PATCH 01/11] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index fc492ed..0205740 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 22 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless%2Fstainless-v0-c05bce23f6a3478a1803494b2c627e0bbf73917a849756eddc42f4607e167c6b.yml -openapi_spec_hash: b9eb999620220d15b176f815f21a67ba +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless%2Fstainless-v0-bced6b6177fa276293bb8c54df90e10340f1b5dd92189225c53551d3952c091a.yml +openapi_spec_hash: ad0459eb77d77055a261721e087ed5da config_hash: 977c436868252591d86546b2127ab8ce From 2bd0c8f519c3273bd20e1fac8b65f6d1dc709a34 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:03:11 +0000 Subject: [PATCH 02/11] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 0205740..fc492ed 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 22 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless%2Fstainless-v0-bced6b6177fa276293bb8c54df90e10340f1b5dd92189225c53551d3952c091a.yml -openapi_spec_hash: ad0459eb77d77055a261721e087ed5da +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless%2Fstainless-v0-c05bce23f6a3478a1803494b2c627e0bbf73917a849756eddc42f4607e167c6b.yml +openapi_spec_hash: b9eb999620220d15b176f815f21a67ba config_hash: 977c436868252591d86546b2127ab8ce From 69b5e8843310e735e26b412c4c8a62a786c8daf8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 15:18:05 +0000 Subject: [PATCH 03/11] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index fc492ed..9630897 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 22 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless%2Fstainless-v0-c05bce23f6a3478a1803494b2c627e0bbf73917a849756eddc42f4607e167c6b.yml -openapi_spec_hash: b9eb999620220d15b176f815f21a67ba +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless%2Fstainless-v0-60fccc45e9e7fac02642f763acadcafbd890990992facb1242864364f7c3fa80.yml +openapi_spec_hash: f4a06d91e54ada059445cd7ab63678b3 config_hash: 977c436868252591d86546b2127ab8ce From 28b4760f8554175e464ac3b8f10eec735ac226fd Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 18:09:43 +0000 Subject: [PATCH 04/11] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 9630897..81e34d0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 22 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless%2Fstainless-v0-60fccc45e9e7fac02642f763acadcafbd890990992facb1242864364f7c3fa80.yml openapi_spec_hash: f4a06d91e54ada059445cd7ab63678b3 -config_hash: 977c436868252591d86546b2127ab8ce +config_hash: 4b44da9496c775d2294758cd233f4ecd From c4dd9e705c0e9d7de3df03f42034e7cd9b4322ec Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 22:18:40 +0000 Subject: [PATCH 05/11] chore(internal): remove mock server code --- scripts/mock | 41 ----------------------------------------- scripts/test | 46 ---------------------------------------------- 2 files changed, 87 deletions(-) delete mode 100755 scripts/mock diff --git a/scripts/mock b/scripts/mock deleted file mode 100755 index 0b28f6e..0000000 --- a/scripts/mock +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd "$(dirname "$0")/.." - -if [[ -n "$1" && "$1" != '--'* ]]; then - URL="$1" - shift -else - URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)" -fi - -# Check if the URL is empty -if [ -z "$URL" ]; then - echo "Error: No OpenAPI spec path/url provided or found in .stats.yml" - exit 1 -fi - -echo "==> Starting mock server with URL ${URL}" - -# Run prism mock on the given spec -if [ "$1" == "--daemon" ]; then - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & - - # Wait for server to come online - echo -n "Waiting for server" - while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do - echo -n "." - sleep 0.1 - done - - if grep -q "✖ fatal" ".prism.log"; then - cat .prism.log - exit 1 - fi - - echo -else - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" -fi diff --git a/scripts/test b/scripts/test index 7383fc5..df2bd61 100755 --- a/scripts/test +++ b/scripts/test @@ -4,53 +4,7 @@ set -euo pipefail cd "$(dirname "$0")/.." -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -NC='\033[0m' # No Color -function prism_is_running() { - curl --silent "http://localhost:4010" >/dev/null 2>&1 -} - -kill_server_on_port() { - pids=$(lsof -t -i tcp:"$1" || echo "") - if [ "$pids" != "" ]; then - kill "$pids" - echo "Stopped $pids." - fi -} - -function is_overriding_api_base_url() { - [ -n "${TEST_API_BASE_URL:-}" ] -} - -if ! is_overriding_api_base_url && ! prism_is_running ; then - # When we exit this script, make sure to kill the background mock server process - trap 'kill_server_on_port 4010' EXIT - - # Start the dev server - ./scripts/mock --daemon -fi - -if is_overriding_api_base_url ; then - echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}" - echo -elif ! prism_is_running ; then - echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server" - echo -e "running against your OpenAPI spec." - echo - echo -e "To run the server, pass in the path or url of your OpenAPI" - echo -e "spec to the prism command:" - echo - echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}" - echo - - exit 1 -else - echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}" - echo -fi echo "==> Running tests" go test ./... "$@" From 5d1a9048221995d8103d5abc945c9a03f1df520a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 08:48:13 +0000 Subject: [PATCH 06/11] feat(api): manual updates --- scripts/mock | 41 +++++++++++++++++++++++++++++++++++++++++ scripts/test | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100755 scripts/mock diff --git a/scripts/mock b/scripts/mock new file mode 100755 index 0000000..0b28f6e --- /dev/null +++ b/scripts/mock @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -e + +cd "$(dirname "$0")/.." + +if [[ -n "$1" && "$1" != '--'* ]]; then + URL="$1" + shift +else + URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)" +fi + +# Check if the URL is empty +if [ -z "$URL" ]; then + echo "Error: No OpenAPI spec path/url provided or found in .stats.yml" + exit 1 +fi + +echo "==> Starting mock server with URL ${URL}" + +# Run prism mock on the given spec +if [ "$1" == "--daemon" ]; then + npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & + + # Wait for server to come online + echo -n "Waiting for server" + while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do + echo -n "." + sleep 0.1 + done + + if grep -q "✖ fatal" ".prism.log"; then + cat .prism.log + exit 1 + fi + + echo +else + npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" +fi diff --git a/scripts/test b/scripts/test index df2bd61..7383fc5 100755 --- a/scripts/test +++ b/scripts/test @@ -4,7 +4,53 @@ set -euo pipefail cd "$(dirname "$0")/.." +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color +function prism_is_running() { + curl --silent "http://localhost:4010" >/dev/null 2>&1 +} + +kill_server_on_port() { + pids=$(lsof -t -i tcp:"$1" || echo "") + if [ "$pids" != "" ]; then + kill "$pids" + echo "Stopped $pids." + fi +} + +function is_overriding_api_base_url() { + [ -n "${TEST_API_BASE_URL:-}" ] +} + +if ! is_overriding_api_base_url && ! prism_is_running ; then + # When we exit this script, make sure to kill the background mock server process + trap 'kill_server_on_port 4010' EXIT + + # Start the dev server + ./scripts/mock --daemon +fi + +if is_overriding_api_base_url ; then + echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}" + echo +elif ! prism_is_running ; then + echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server" + echo -e "running against your OpenAPI spec." + echo + echo -e "To run the server, pass in the path or url of your OpenAPI" + echo -e "spec to the prism command:" + echo + echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}" + echo + + exit 1 +else + echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}" + echo +fi echo "==> Running tests" go test ./... "$@" From 27237e28927e936ca9efe213baef180933a050ea Mon Sep 17 00:00:00 2001 From: Young-jin Park Date: Fri, 20 Feb 2026 01:26:17 -0800 Subject: [PATCH 07/11] fix: fix project creation --- pkg/cmd/init.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/cmd/init.go b/pkg/cmd/init.go index 09f3537..2973172 100644 --- a/pkg/cmd/init.go +++ b/pkg/cmd/init.go @@ -220,7 +220,7 @@ func fetchUserProjects(ctx context.Context, client stainless.Client, org string) // askSelectProject prompts the user to select from existing projects or create a new one func askSelectProject(projects []stainless.Project) (string, *stainless.Project, error) { options := make([]huh.Option[*stainless.Project], 0, len(projects)+1) - options = append(options, huh.NewOption("", &stainless.Project{})) + options = append(options, huh.NewOption("", (*stainless.Project)(nil))) projects = slices.SortedFunc(slices.Values(projects), func(p1, p2 stainless.Project) int { if p1.Slug < p2.Slug { return -1 @@ -240,6 +240,9 @@ func askSelectProject(projects []stainless.Project) (string, *stainless.Project, if err != nil { return "", nil, err } + if picked == nil { + return "", nil, nil + } return picked.Slug, picked, nil } From 5e5b7cfdfc7cb5f1baa72cb2d74b016d7f78558c Mon Sep 17 00:00:00 2001 From: Young-jin Park Date: Fri, 20 Feb 2026 01:28:59 -0800 Subject: [PATCH 08/11] feat: remove unused dev.TickMsg --- pkg/components/dev/model.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pkg/components/dev/model.go b/pkg/components/dev/model.go index 073b2be..61aac63 100644 --- a/pkg/components/dev/model.go +++ b/pkg/components/dev/model.go @@ -3,7 +3,6 @@ package dev import ( "context" "errors" - "time" "github.com/charmbracelet/bubbles/help" "github.com/charmbracelet/bubbles/key" @@ -34,7 +33,6 @@ type Model struct { Diagnostics diagnostics.Model } -type TickMsg time.Time type ErrorMsg error type FileChangeMsg struct{} @@ -52,9 +50,8 @@ func NewModel(client stainless.Client, ctx context.Context, branch string, fn fu func (m Model) Init() tea.Cmd { return tea.Batch( - tea.Tick(time.Second, func(t time.Time) tea.Msg { - return TickMsg(t) - }), + m.Build.Init(), + m.Diagnostics.Init(), func() tea.Msg { res, err := m.start() if err != nil { @@ -62,8 +59,6 @@ func (m Model) Init() tea.Cmd { } return build.FetchBuildMsg(*res) }, - m.Build.Init(), - m.Diagnostics.Init(), ) } From c4d186657c0f944a9dc736df4280d8c4fb77fc38 Mon Sep 17 00:00:00 2001 From: Young-jin Park Date: Fri, 20 Feb 2026 01:29:17 -0800 Subject: [PATCH 09/11] fix: improve error handling in build errors --- pkg/components/build/model.go | 1 + pkg/components/build/view.go | 3 +++ pkg/components/dev/view.go | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/pkg/components/build/model.go b/pkg/components/build/model.go index cbb1088..af4b926 100644 --- a/pkg/components/build/model.go +++ b/pkg/components/build/model.go @@ -121,6 +121,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { case ErrorMsg: m.Err = msg + cmds = append(cmds, tea.Quit) } return m, tea.Batch(cmds...) diff --git a/pkg/components/build/view.go b/pkg/components/build/view.go index 258b7d2..78bd5d5 100644 --- a/pkg/components/build/view.go +++ b/pkg/components/build/view.go @@ -11,6 +11,9 @@ import ( ) func (m Model) View() string { + if m.Err != nil { + return m.Err.Error() + } return View(m.Build, m.Downloads) } diff --git a/pkg/components/dev/view.go b/pkg/components/dev/view.go index 853f437..c9dd85a 100644 --- a/pkg/components/dev/view.go +++ b/pkg/components/dev/view.go @@ -11,6 +11,10 @@ import ( ) func (m Model) View() string { + if m.Err != nil { + return m.Err.Error() + } + s := strings.Builder{} idx := slices.IndexFunc(parts, func(part ViewPart) bool { From 93e3e0cfb46c70982b70b9768200d8ce992326dd Mon Sep 17 00:00:00 2001 From: Young-jin Park Date: Fri, 20 Feb 2026 01:47:39 -0800 Subject: [PATCH 10/11] feat: add CommitOnly option to build model --- pkg/cmd/build.go | 5 ++++- pkg/cmd/init.go | 5 ++++- pkg/components/build/model.go | 3 ++- pkg/components/build/view.go | 11 +++++++---- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/pkg/cmd/build.go b/pkg/cmd/build.go index d6f6126..09be974 100644 --- a/pkg/cmd/build.go +++ b/pkg/cmd/build.go @@ -430,8 +430,10 @@ func handleBuildsCreate(ctx context.Context, cmd *cli.Command) error { if waitMode > WaitNone { console.Spacer() + buildModel := cbuild.NewModel(client, ctx, *build, cmd.String("branch"), downloadPaths) + buildModel.CommitOnly = waitMode == WaitCommit model := tea.Model(buildCompletionModel{ - Build: cbuild.NewModel(client, ctx, *build, cmd.String("branch"), downloadPaths), + Build: buildModel, WaitMode: waitMode, }) model, err = tea.NewProgram(model).Run() @@ -541,6 +543,7 @@ func (c buildCompletionModel) IsCompleted() bool { } func (c buildCompletionModel) View() string { + c.Build.CommitOnly = c.WaitMode == WaitCommit return c.Build.View() } diff --git a/pkg/cmd/init.go b/pkg/cmd/init.go index 2973172..6b24460 100644 --- a/pkg/cmd/init.go +++ b/pkg/cmd/init.go @@ -425,8 +425,11 @@ func initializeWorkspace(ctx context.Context, cmd *cli.Command, client stainless downloadPaths[stainless.Target(targetName)] = targetConfig.OutputPath } + buildModel := cbuild.NewModel(client, ctx, *build, "main", downloadPaths) + buildModel.CommitOnly = true model := buildCompletionModel{ - Build: cbuild.NewModel(client, ctx, *build, "main", downloadPaths), + Build: buildModel, + WaitMode: WaitCommit, } _, err = tea.NewProgram(model).Run() diff --git a/pkg/components/build/model.go b/pkg/components/build/model.go index af4b926..c9aaec2 100644 --- a/pkg/components/build/model.go +++ b/pkg/components/build/model.go @@ -28,7 +28,8 @@ type Model struct { Ctx context.Context Branch string // Optional branch name for git checkout Downloads map[stainless.Target]DownloadStatus // When a BuildTarget has a commit available, this target will download it, if it has been specified in the initialization. - Err error // This will be populated if the model concludes with an error + Err error // This will be populated if the model concludes with an error + CommitOnly bool // When true, only show the commit step in the pipeline view } type DownloadStatus struct { diff --git a/pkg/components/build/view.go b/pkg/components/build/view.go index 78bd5d5..1a524e6 100644 --- a/pkg/components/build/view.go +++ b/pkg/components/build/view.go @@ -14,16 +14,16 @@ func (m Model) View() string { if m.Err != nil { return m.Err.Error() } - return View(m.Build, m.Downloads) + return View(m.Build, m.Downloads, m.CommitOnly) } -func View(build stainless.Build, downloads map[stainless.Target]DownloadStatus) string { +func View(build stainless.Build, downloads map[stainless.Target]DownloadStatus, commitOnly bool) string { s := strings.Builder{} buildObj := stainlessutils.NewBuild(build) languages := buildObj.Languages() // Target rows with colors for _, target := range languages { - pipeline := ViewBuildPipeline(build, target, downloads) + pipeline := ViewBuildPipeline(build, target, downloads, commitOnly) langStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("15")).Bold(true) s.WriteString(fmt.Sprintf("%s %s\n", langStyle.Render(fmt.Sprintf("%-13s", string(target))), pipeline)) @@ -53,7 +53,7 @@ func View(build stainless.Build, downloads map[stainless.Target]DownloadStatus) } // View renders the build pipeline for a target -func ViewBuildPipeline(build stainless.Build, target stainless.Target, downloads map[stainless.Target]DownloadStatus) string { +func ViewBuildPipeline(build stainless.Build, target stainless.Target, downloads map[stainless.Target]DownloadStatus, commitOnly bool) string { buildObj := stainlessutils.NewBuild(build) buildTarget := buildObj.BuildTarget(target) if buildTarget == nil { @@ -64,6 +64,9 @@ func ViewBuildPipeline(build stainless.Build, target stainless.Target, downloads var pipeline strings.Builder for _, step := range stepOrder { + if commitOnly && step != "commit" { + continue + } status, url, conclusion := buildTarget.StepInfo(step) if status == "" { continue // Skip steps that don't exist for this target From 836d4ace31fe1503ccc01979ac2651bcc15dd57b Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 25 Feb 2026 02:59:18 +0100 Subject: [PATCH 11/11] release: 0.1.0-alpha.74 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 21 +++++++++++++++++++++ pkg/cmd/version.go | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 7b7f1c5..b476488 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.73" + ".": "0.1.0-alpha.74" } diff --git a/CHANGELOG.md b/CHANGELOG.md index ae0b65f..95fb6a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## 0.1.0-alpha.74 (2026-02-25) + +Full Changelog: [v0.1.0-alpha.73...v0.1.0-alpha.74](https://github.com/stainless-api/stainless-api-cli/compare/v0.1.0-alpha.73...v0.1.0-alpha.74) + +### Features + +* add CommitOnly option to build model ([93e3e0c](https://github.com/stainless-api/stainless-api-cli/commit/93e3e0cfb46c70982b70b9768200d8ce992326dd)) +* **api:** manual updates ([5d1a904](https://github.com/stainless-api/stainless-api-cli/commit/5d1a9048221995d8103d5abc945c9a03f1df520a)) +* remove unused dev.TickMsg ([5e5b7cf](https://github.com/stainless-api/stainless-api-cli/commit/5e5b7cfdfc7cb5f1baa72cb2d74b016d7f78558c)) + + +### Bug Fixes + +* fix project creation ([27237e2](https://github.com/stainless-api/stainless-api-cli/commit/27237e28927e936ca9efe213baef180933a050ea)) +* improve error handling in build errors ([c4d1866](https://github.com/stainless-api/stainless-api-cli/commit/c4d186657c0f944a9dc736df4280d8c4fb77fc38)) + + +### Chores + +* **internal:** remove mock server code ([c4dd9e7](https://github.com/stainless-api/stainless-api-cli/commit/c4dd9e705c0e9d7de3df03f42034e7cd9b4322ec)) + ## 0.1.0-alpha.73 (2026-02-20) Full Changelog: [v0.1.0-alpha.72...v0.1.0-alpha.73](https://github.com/stainless-api/stainless-api-cli/compare/v0.1.0-alpha.72...v0.1.0-alpha.73) diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index 2b395e0..b1c4ba3 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -2,4 +2,4 @@ package cmd -const Version = "0.1.0-alpha.73" // x-release-please-version +const Version = "0.1.0-alpha.74" // x-release-please-version