From 7fea1660f3d17d8a35f5d2f6aa352b553785624b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 24 Jan 2026 07:14:41 +0000
Subject: [PATCH 1/5] feat(client): add a convenient param.SetJSON helper
---
packages/param/param.go | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/packages/param/param.go b/packages/param/param.go
index 6873e09..44dd849 100644
--- a/packages/param/param.go
+++ b/packages/param/param.go
@@ -41,6 +41,19 @@ func Override[T ParamStruct, PtrT InferPtr[T]](v any) T {
return *pt
}
+// SetJSON configures a param struct to serialize with the provided raw JSON data.
+// Use this when you have existing JSON that you want to send as request parameters.
+//
+// var req example.NewUserParams
+// var rawJSON = []byte(`{"name": "...", "age": 40}`)
+// param.SetJSON(rawJSON, &req)
+// res, err := client.Users.New(ctx, req)
+//
+// Note: The struct's existing fields will be ignored; only the provided JSON is serialized.
+func SetJSON(rawJSON []byte, ptr anyParamStruct) {
+ ptr.setMetadata(json.RawMessage(rawJSON))
+}
+
// IsOmitted returns true if v is the zero value of its type.
//
// If IsOmitted is true, and the field uses a `json:"...,omitzero"` tag,
@@ -91,6 +104,11 @@ type ParamStruct interface {
extraFields() map[string]any
}
+// A pointer to ParamStruct
+type anyParamStruct interface {
+ setMetadata(any)
+}
+
// This is an implementation detail and should never be explicitly set.
type InferPtr[T ParamStruct] interface {
setMetadata(any)
From 0e29d03d94cf50a0d0e83c323f7ed9f2e15f3e61 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 27 Jan 2026 20:14:43 +0000
Subject: [PATCH 2/5] feat(builds): implement two-tier build cache with
per-repo token scopes
---
.stats.yml | 4 ++--
build.go | 36 +++++++++++++++++++++++-------------
build_test.go | 2 ++
3 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 7320373..66f7a97 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-4f6187089a62f5df123ef4ee17660dd737c2b486377af2b5c5a922d454067b41.yml
-openapi_spec_hash: 53e42659f7453f1abfda3236c3f7cb31
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-fbe706932aedef16a8bb04fe361b1e8659ae074ff9122f4e9e28914087a677b8.yml
+openapi_spec_hash: 6ba4858b44cb317676c58f33bfa1426a
config_hash: 14135b7c88169a15762c8defb0bdfd16
diff --git a/build.go b/build.go
index b10833e..abb84b3 100644
--- a/build.go
+++ b/build.go
@@ -117,6 +117,8 @@ type Build struct {
//
// Any of "queued", "building", "pushing", "ready", "failed", "cancelled".
Status BuildStatus `json:"status,required"`
+ // Instance ID of the builder VM (for debugging)
+ BuilderInstanceID string `json:"builder_instance_id,nullable"`
// Build completion timestamp
CompletedAt time.Time `json:"completed_at,nullable" format:"date-time"`
// Build duration in milliseconds
@@ -134,19 +136,20 @@ type Build struct {
StartedAt time.Time `json:"started_at,nullable" format:"date-time"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- ID respjson.Field
- CreatedAt respjson.Field
- Status respjson.Field
- CompletedAt respjson.Field
- DurationMs respjson.Field
- Error respjson.Field
- ImageDigest respjson.Field
- ImageRef respjson.Field
- Provenance respjson.Field
- QueuePosition respjson.Field
- StartedAt respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ ID respjson.Field
+ CreatedAt respjson.Field
+ Status respjson.Field
+ BuilderInstanceID respjson.Field
+ CompletedAt respjson.Field
+ DurationMs respjson.Field
+ Error respjson.Field
+ ImageDigest respjson.Field
+ ImageRef respjson.Field
+ Provenance respjson.Field
+ QueuePosition respjson.Field
+ StartedAt respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
@@ -245,6 +248,13 @@ type BuildNewParams struct {
CacheScope param.Opt[string] `json:"cache_scope,omitzero"`
// Dockerfile content. Required if not included in the source tarball.
Dockerfile param.Opt[string] `json:"dockerfile,omitzero"`
+ // Global cache identifier (e.g., "node", "python", "ubuntu", "browser"). When
+ // specified, the build will import from cache/global/{key}. Admin builds will also
+ // export to this location.
+ GlobalCacheKey param.Opt[string] `json:"global_cache_key,omitzero"`
+ // Set to "true" to grant push access to global cache (operator-only). Admin builds
+ // can populate the shared global cache that all tenant builds read from.
+ IsAdminBuild param.Opt[string] `json:"is_admin_build,omitzero"`
// JSON array of secret references to inject during build. Each object has "id"
// (required) for use with --mount=type=secret,id=... Example: [{"id":
// "npm_token"}, {"id": "github_token"}]
diff --git a/build_test.go b/build_test.go
index a76dbb6..27c129c 100644
--- a/build_test.go
+++ b/build_test.go
@@ -33,6 +33,8 @@ func TestBuildNewWithOptionalParams(t *testing.T) {
BaseImageDigest: hypeman.String("base_image_digest"),
CacheScope: hypeman.String("cache_scope"),
Dockerfile: hypeman.String("dockerfile"),
+ GlobalCacheKey: hypeman.String("global_cache_key"),
+ IsAdminBuild: hypeman.String("is_admin_build"),
Secrets: hypeman.String("secrets"),
TimeoutSeconds: hypeman.Int(0),
})
From db5600fb473c50b4cfa02413d02b867ce26f5e90 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 28 Jan 2026 17:43:09 +0000
Subject: [PATCH 3/5] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 66f7a97..cf81e7b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-fbe706932aedef16a8bb04fe361b1e8659ae074ff9122f4e9e28914087a677b8.yml
openapi_spec_hash: 6ba4858b44cb317676c58f33bfa1426a
-config_hash: 14135b7c88169a15762c8defb0bdfd16
+config_hash: 641863d262a79cb16a7ff0d849ab12e1
From 95ddadb4f53fd6124dd10a0b5c65b6de3b7bc365 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 28 Jan 2026 17:47:31 +0000
Subject: [PATCH 4/5] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index cf81e7b..4f62196 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-fbe706932aedef16a8bb04fe361b1e8659ae074ff9122f4e9e28914087a677b8.yml
openapi_spec_hash: 6ba4858b44cb317676c58f33bfa1426a
-config_hash: 641863d262a79cb16a7ff0d849ab12e1
+config_hash: 1cdf82c4ccf2d607bedcdd5de63154fe
From f60e60015bb9ce18c7083963d9ecd11c980de495 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 28 Jan 2026 20:26:39 +0000
Subject: [PATCH 5/5] feat(api): manual updates
---
.stats.yml | 2 +-
README.md | 2 +-
api.md | 51 ++++++++++++++++++++++++++-------------------------
3 files changed, 28 insertions(+), 27 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 4f62196..5e112da 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fhypeman-fbe706932aedef16a8bb04fe361b1e8659ae074ff9122f4e9e28914087a677b8.yml
openapi_spec_hash: 6ba4858b44cb317676c58f33bfa1426a
-config_hash: 1cdf82c4ccf2d607bedcdd5de63154fe
+config_hash: 542144891263a3626eabcb2fd4f4f3e5
diff --git a/README.md b/README.md
index d20968d..0b76851 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ Or to pin the version:
```sh
-go get -u 'github.com/kernel/hypeman-go@v0.9.0'
+go get -u 'github.com/kernel/hypeman-go@v0.8.0'
```
diff --git a/api.md b/api.md
index ae9d5bb..4255a7d 100644
--- a/api.md
+++ b/api.md
@@ -6,7 +6,7 @@ Response Types:
Methods:
-- client.Health.Check(ctx context.Context) (hypeman.HealthCheckResponse, error)
+- client.Health.Check(ctx context.Context) (\*hypeman.HealthCheckResponse, error)
# Images
@@ -16,10 +16,10 @@ Response Types:
Methods:
-- client.Images.New(ctx context.Context, body hypeman.ImageNewParams) (hypeman.Image, error)
-- client.Images.List(ctx context.Context) ([]hypeman.Image, error)
+- client.Images.New(ctx context.Context, body hypeman.ImageNewParams) (\*hypeman.Image, error)
+- client.Images.List(ctx context.Context) (\*[]hypeman.Image, error)
- client.Images.Delete(ctx context.Context, name string) error
-- client.Images.Get(ctx context.Context, name string) (hypeman.Image, error)
+- client.Images.Get(ctx context.Context, name string) (\*hypeman.Image, error)
# Instances
@@ -35,23 +35,23 @@ Response Types:
Methods:
-- client.Instances.New(ctx context.Context, body hypeman.InstanceNewParams) (hypeman.Instance, error)
-- client.Instances.List(ctx context.Context) ([]hypeman.Instance, error)
+- client.Instances.New(ctx context.Context, body hypeman.InstanceNewParams) (\*hypeman.Instance, error)
+- client.Instances.List(ctx context.Context) (\*[]hypeman.Instance, error)
- client.Instances.Delete(ctx context.Context, id string) error
-- client.Instances.Get(ctx context.Context, id string) (hypeman.Instance, error)
-- 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.Stat(ctx context.Context, id string, query hypeman.InstanceStatParams) (hypeman.PathInfo, error)
-- client.Instances.Stop(ctx context.Context, id string) (hypeman.Instance, error)
+- client.Instances.Get(ctx context.Context, id string) (\*hypeman.Instance, error)
+- 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.Stat(ctx context.Context, id string, query hypeman.InstanceStatParams) (\*hypeman.PathInfo, error)
+- client.Instances.Stop(ctx context.Context, id string) (\*hypeman.Instance, error)
## Volumes
Methods:
-- client.Instances.Volumes.Attach(ctx context.Context, volumeID string, params hypeman.InstanceVolumeAttachParams) (hypeman.Instance, error)
-- client.Instances.Volumes.Detach(ctx context.Context, volumeID string, body hypeman.InstanceVolumeDetachParams) (hypeman.Instance, error)
+- client.Instances.Volumes.Attach(ctx context.Context, volumeID string, params hypeman.InstanceVolumeAttachParams) (\*hypeman.Instance, error)
+- client.Instances.Volumes.Detach(ctx context.Context, volumeID string, body hypeman.InstanceVolumeDetachParams) (\*hypeman.Instance, error)
# Volumes
@@ -62,10 +62,10 @@ Response Types:
Methods:
-- client.Volumes.New(ctx context.Context, body hypeman.VolumeNewParams) (hypeman.Volume, error)
-- client.Volumes.List(ctx context.Context) ([]hypeman.Volume, error)
+- client.Volumes.New(ctx context.Context, body hypeman.VolumeNewParams) (\*hypeman.Volume, error)
+- client.Volumes.List(ctx context.Context) (\*[]hypeman.Volume, error)
- client.Volumes.Delete(ctx context.Context, id string) error
-- client.Volumes.Get(ctx context.Context, id string) (hypeman.Volume, error)
+- client.Volumes.Get(ctx context.Context, id string) (\*hypeman.Volume, error)
# Devices
@@ -77,11 +77,11 @@ Response Types:
Methods:
-- client.Devices.New(ctx context.Context, body hypeman.DeviceNewParams) (hypeman.Device, error)
-- client.Devices.Get(ctx context.Context, id string) (hypeman.Device, error)
-- client.Devices.List(ctx context.Context) ([]hypeman.Device, error)
+- client.Devices.New(ctx context.Context, body hypeman.DeviceNewParams) (\*hypeman.Device, error)
+- client.Devices.Get(ctx context.Context, id string) (\*hypeman.Device, error)
+- client.Devices.List(ctx context.Context) (\*[]hypeman.Device, error)
- client.Devices.Delete(ctx context.Context, id string) error
-- client.Devices.ListAvailable(ctx context.Context) ([]hypeman.AvailableDevice, error)
+- client.Devices.ListAvailable(ctx context.Context) (\*[]hypeman.AvailableDevice, error)
# Ingresses
@@ -100,10 +100,11 @@ Response Types:
Methods:
-- client.Ingresses.New(ctx context.Context, body hypeman.IngressNewParams) (hypeman.Ingress, error)
-- client.Ingresses.List(ctx context.Context) ([]hypeman.Ingress, error)
+- client.Ingresses.New(ctx context.Context, body hypeman.IngressNewParams) (\*hypeman.Ingress, error)
+- client.Ingresses.List(ctx context.Context) (\*[]hypeman.Ingress, error)
- client.Ingresses.Delete(ctx context.Context, id string) error
-- client.Ingresses.Get(ctx context.Context, id string) (hypeman.Ingress, error)
+- client.Ingresses.Get(ctx context.Context, id string) (\*hypeman.Ingress, error)
+
# Resources
Response Types: