From f3de06d220faf866b70829862cd1b76ee4e8fbf8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 05:24:01 +0000 Subject: [PATCH 1/6] chore(internal): codegen related update --- internal/paramutil/sentinel.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 internal/paramutil/sentinel.go diff --git a/internal/paramutil/sentinel.go b/internal/paramutil/sentinel.go new file mode 100644 index 0000000..3d97ff6 --- /dev/null +++ b/internal/paramutil/sentinel.go @@ -0,0 +1,31 @@ +package paramutil + +import ( + "github.com/onkernel/hypeman-go/internal/encoding/json/sentinel" +) + +// NullPtr returns a pointer to the zero value of the type T. +// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null. +// +// It is unspecified behavior to mutate the value pointed to by the returned pointer. +func NullPtr[T any]() *T { + return sentinel.NullPtr[T]() +} + +// IsNullPtr returns true if the pointer was created by [NullPtr]. +func IsNullPtr[T any](ptr *T) bool { + return sentinel.IsNullPtr(ptr) +} + +// NullSlice returns a non-nil slice with a length of 0. +// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null. +// +// It is undefined behavior to mutate the slice returned by [NullSlice]. +func NullSlice[T any]() []T { + return sentinel.NullSlice[T]() +} + +// IsNullSlice returns true if the slice was created by [NullSlice]. +func IsNullSlice[T any](slice []T) bool { + return sentinel.IsNullSlice(slice) +} From 9be276faa6d683ddffe3a21c969b44f13acface0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 05:24:48 +0000 Subject: [PATCH 2/6] chore: elide duplicate aliases --- internal/paramutil/sentinel.go | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 internal/paramutil/sentinel.go diff --git a/internal/paramutil/sentinel.go b/internal/paramutil/sentinel.go deleted file mode 100644 index 3d97ff6..0000000 --- a/internal/paramutil/sentinel.go +++ /dev/null @@ -1,31 +0,0 @@ -package paramutil - -import ( - "github.com/onkernel/hypeman-go/internal/encoding/json/sentinel" -) - -// NullPtr returns a pointer to the zero value of the type T. -// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null. -// -// It is unspecified behavior to mutate the value pointed to by the returned pointer. -func NullPtr[T any]() *T { - return sentinel.NullPtr[T]() -} - -// IsNullPtr returns true if the pointer was created by [NullPtr]. -func IsNullPtr[T any](ptr *T) bool { - return sentinel.IsNullPtr(ptr) -} - -// NullSlice returns a non-nil slice with a length of 0. -// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null. -// -// It is undefined behavior to mutate the slice returned by [NullSlice]. -func NullSlice[T any]() []T { - return sentinel.NullSlice[T]() -} - -// IsNullSlice returns true if the slice was created by [NullSlice]. -func IsNullSlice[T any](slice []T) bool { - return sentinel.IsNullSlice(slice) -} From 0d8715273698dab9bb6c276352a13605ddd272a5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 05:25:23 +0000 Subject: [PATCH 3/6] fix(mcp): correct code tool API endpoint --- internal/paramutil/sentinel.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 internal/paramutil/sentinel.go diff --git a/internal/paramutil/sentinel.go b/internal/paramutil/sentinel.go new file mode 100644 index 0000000..3d97ff6 --- /dev/null +++ b/internal/paramutil/sentinel.go @@ -0,0 +1,31 @@ +package paramutil + +import ( + "github.com/onkernel/hypeman-go/internal/encoding/json/sentinel" +) + +// NullPtr returns a pointer to the zero value of the type T. +// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null. +// +// It is unspecified behavior to mutate the value pointed to by the returned pointer. +func NullPtr[T any]() *T { + return sentinel.NullPtr[T]() +} + +// IsNullPtr returns true if the pointer was created by [NullPtr]. +func IsNullPtr[T any](ptr *T) bool { + return sentinel.IsNullPtr(ptr) +} + +// NullSlice returns a non-nil slice with a length of 0. +// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null. +// +// It is undefined behavior to mutate the slice returned by [NullSlice]. +func NullSlice[T any]() []T { + return sentinel.NullSlice[T]() +} + +// IsNullSlice returns true if the slice was created by [NullSlice]. +func IsNullSlice[T any](slice []T) bool { + return sentinel.IsNullSlice(slice) +} From f1ec9d52e3f5f6c8398bdded04a4ed9cfbd8151b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 05:25:57 +0000 Subject: [PATCH 4/6] fix: rename param to avoid collision --- internal/paramutil/sentinel.go | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 internal/paramutil/sentinel.go diff --git a/internal/paramutil/sentinel.go b/internal/paramutil/sentinel.go deleted file mode 100644 index 3d97ff6..0000000 --- a/internal/paramutil/sentinel.go +++ /dev/null @@ -1,31 +0,0 @@ -package paramutil - -import ( - "github.com/onkernel/hypeman-go/internal/encoding/json/sentinel" -) - -// NullPtr returns a pointer to the zero value of the type T. -// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null. -// -// It is unspecified behavior to mutate the value pointed to by the returned pointer. -func NullPtr[T any]() *T { - return sentinel.NullPtr[T]() -} - -// IsNullPtr returns true if the pointer was created by [NullPtr]. -func IsNullPtr[T any](ptr *T) bool { - return sentinel.IsNullPtr(ptr) -} - -// NullSlice returns a non-nil slice with a length of 0. -// When used with [MarshalObject] or [MarshalUnion], it will be marshaled as null. -// -// It is undefined behavior to mutate the slice returned by [NullSlice]. -func NullSlice[T any]() []T { - return sentinel.NullSlice[T]() -} - -// IsNullSlice returns true if the slice was created by [NullSlice]. -func IsNullSlice[T any](slice []T) bool { - return sentinel.IsNullSlice(slice) -} From b99222818b197010ba324c2e2477047e5bf13802 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 14:03:55 +0000 Subject: [PATCH 5/6] feat: Start and Stop VM --- .stats.yml | 8 ++++---- api.md | 2 ++ instance.go | 24 ++++++++++++++++++++++++ instance_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 96e35f6..f1158e6 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/kernel%2Fhypeman-da3f4038bb544acae375f44527f515dc58308f67822905258b155192041e65ed.yml -openapi_spec_hash: 4c7f6f453c20eda7fd8689e8917c65f9 -config_hash: a7d0557c72de54fd6baded5b189777c3 +configured_endpoints: 24 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-6a8902e840cc8f443018c06b23884d3b42e45181c1ac156f5cf56cac84b717ee.yml +openapi_spec_hash: d1535b5fdc9d097940928f0689c8baa1 +config_hash: 510018ffa6ad6a17875954f66fe69598 diff --git a/api.md b/api.md index 81727b9..11cb961 100644 --- a/api.md +++ b/api.md @@ -41,6 +41,8 @@ Methods: - client.Instances.Logs(ctx context.Context, id string, query hypeman.InstanceLogsParams) (string, error) - client.Instances.Restore(ctx context.Context, id string) (hypeman.Instance, error) - client.Instances.Standby(ctx context.Context, id string) (hypeman.Instance, error) +- client.Instances.Start(ctx context.Context, id string) (hypeman.Instance, error) +- client.Instances.Stop(ctx context.Context, id string) (hypeman.Instance, error) ## Volumes diff --git a/instance.go b/instance.go index 2f9d571..21ff287 100644 --- a/instance.go +++ b/instance.go @@ -126,6 +126,30 @@ func (r *InstanceService) Standby(ctx context.Context, id string, opts ...option return } +// Start a stopped instance +func (r *InstanceService) Start(ctx context.Context, id string, opts ...option.RequestOption) (res *Instance, err error) { + opts = slices.Concat(r.Options, opts) + if id == "" { + err = errors.New("missing required id parameter") + return + } + path := fmt.Sprintf("instances/%s/start", id) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) + return +} + +// Stop instance (graceful shutdown) +func (r *InstanceService) Stop(ctx context.Context, id string, opts ...option.RequestOption) (res *Instance, err error) { + opts = slices.Concat(r.Options, opts) + if id == "" { + err = errors.New("missing required id parameter") + return + } + path := fmt.Sprintf("instances/%s/stop", id) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) + return +} + type Instance struct { // Auto-generated unique identifier (CUID2 format) ID string `json:"id,required"` diff --git a/instance_test.go b/instance_test.go index d8ba3a7..4910848 100644 --- a/instance_test.go +++ b/instance_test.go @@ -171,3 +171,49 @@ func TestInstanceStandby(t *testing.T) { t.Fatalf("err should be nil: %s", err.Error()) } } + +func TestInstanceStart(t *testing.T) { + t.Skip("Prism tests are disabled") + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := hypeman.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("My API Key"), + ) + _, err := client.Instances.Start(context.TODO(), "id") + if err != nil { + var apierr *hypeman.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestInstanceStop(t *testing.T) { + t.Skip("Prism tests are disabled") + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := hypeman.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("My API Key"), + ) + _, err := client.Instances.Stop(context.TODO(), "id") + if err != nil { + var apierr *hypeman.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} From 0c62a388466b61595837e3f89c0a1e3cd6851a96 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 14:04:28 +0000 Subject: [PATCH 6/6] release: 0.6.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 20 ++++++++++++++++++++ README.md | 2 +- internal/version.go | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2aca35a..4208b5c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.5.0" + ".": "0.6.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2feb3ad..bfc3ea1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## 0.6.0 (2025-12-06) + +Full Changelog: [v0.5.0...v0.6.0](https://github.com/onkernel/hypeman-go/compare/v0.5.0...v0.6.0) + +### Features + +* Start and Stop VM ([b992228](https://github.com/onkernel/hypeman-go/commit/b99222818b197010ba324c2e2477047e5bf13802)) + + +### Bug Fixes + +* **mcp:** correct code tool API endpoint ([0d87152](https://github.com/onkernel/hypeman-go/commit/0d8715273698dab9bb6c276352a13605ddd272a5)) +* rename param to avoid collision ([f1ec9d5](https://github.com/onkernel/hypeman-go/commit/f1ec9d52e3f5f6c8398bdded04a4ed9cfbd8151b)) + + +### Chores + +* elide duplicate aliases ([9be276f](https://github.com/onkernel/hypeman-go/commit/9be276faa6d683ddffe3a21c969b44f13acface0)) +* **internal:** codegen related update ([f3de06d](https://github.com/onkernel/hypeman-go/commit/f3de06d220faf866b70829862cd1b76ee4e8fbf8)) + ## 0.5.0 (2025-12-05) Full Changelog: [v0.4.0...v0.5.0](https://github.com/onkernel/hypeman-go/compare/v0.4.0...v0.5.0) diff --git a/README.md b/README.md index a5c9ecb..4a08602 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Or to pin the version: ```sh -go get -u 'github.com/onkernel/hypeman-go@v0.5.0' +go get -u 'github.com/onkernel/hypeman-go@v0.6.0' ``` diff --git a/internal/version.go b/internal/version.go index 67c4d40..577a4dc 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.5.0" // x-release-please-version +const PackageVersion = "0.6.0" // x-release-please-version